gpt4 book ai didi

c# - 如何告诉 EF 不要在 Code First 中更新引用类型属性?

转载 作者:太空宇宙 更新时间:2023-11-03 13:03:05 26 4
gpt4 key购买 nike

假设我有这两个模型

class Phone
{
public int ID { get; set; }
public string IMEI { get; set;}

public void Encrypt()
{
Encryptor.Encrypt(IMEI);
}
}

class Person
{
public int ID { get; set; }
public Phone Purchase { get; set; }

public void Encrypt()
{
Purchase.Encrypt();
}
}

现在碰巧,为了安全起见,我不能将 IMEI 以明文形式存储在数据库中,所以我使用了我被迫使用的加密方法;即使对于相同的原始字符串,它也会返回不同的加密字符串。每次将值分别保存到数据库和从数据库检索时,我也有一些逻辑来加密和解密字符串。

那么,问题是什么?问题是,当我创建一个新的 Person 时,为其分配一个电话并保存它,EF 也会尝试保存该电话,并且鉴于电话上的 IMEI 字符串已更改,它将使数据库中的新条目。

有没有一种方法可以告诉 EF 不需要保存给定的对象?这样我就可以告诉它保存人及其与电话的关系,而不是电话本身?或者可能是放弃对象中的更改以便 EF 忽略它的方法?

更新1

我有一些辅助类来简化 Controller 中的逻辑,如下所示:

public class Helpers
{
protected CustomDBContext Context { get; } = new CustomDBContext();

public List<Phone> GetPhones()
{
return Context.Phones.Decrypt();
}

public void Save(List<Phone> phones)
{
phones.Encrypt();
Context.Phones.AddRange(phones);
Context.SaveChanges();
}

public List<Person> GetPeople()
{
return Context.Persons.Decrypt();
}

public void Save(List<Person> people)
{
people.Encrypt();
Context.Persons.AddRange(people);
Context.SaveChanges();
}
}

我还更新了上面的原始定义。备注:

  • Person 中的 Encrypt 方法就在那里,因为当我保存 Person 时,它的附加电话也被保存,这是我试图避免的。
  • Encryptor 类中,我有扩展方法来加密列表中的所有对象,这是一个基本的迭代和加密。
  • 我实际上有更多的类和继承以及整个 shebang,为了这个问题的目的我简化了它。

最佳答案

在保存实体之前,将其导航属性设置为 null。这将保留外键但删除与导航属性关联的实体引用。在图形中搜索要添加的实体时,它将找不到任何东西来代替导航属性。

public void Save(List<Person> people)
{
people.Encrypt();

foreach(var person in people){
person.Purchase = null;
}

Context.Person.AddRange(people);
Context.SaveChanges();
}


更新

确保您的实体的导航属性也正确建模。

class Phone
{
public int ID { get; set; }
public string IMEI { get; set;}

public virtual ICollection<Person> People { get; set; }

public void Encrypt()
{
Encryptor.Encrypt(IMEI);
}
}

class Person
{
public int ID { get; set; }
public int PhoneId { get; set; }

public virtual Phone Purchase { get; set; }

public void Encrypt()
{
Purchase.Encrypt();
}
}

您可以在文档中找到有关导航属性的更多信息:https://msdn.microsoft.com/en-us/data/jj713564.aspx


更新2

如果您要更新导航属性并添加父实体,只需在保存前将它们附加到上下文即可。

public void Save(List<Person> people)
{
people.Encrypt();

foreach(var person in people){
Context.Phones.Attach(person.Purchase)
}

Context.Person.AddRange(people);
Context.SaveChanges();
}

这将允许您在每次保存时更新数据库中的加密 IMEI。

关于c# - 如何告诉 EF 不要在 Code First 中更新引用类型属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31769055/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com