我注意到当我存储具有属性为另一种类型的对象时,它会被保存,但链接的属性也是如此。当两者都是新的或两者都在更新时,它都很整洁。
class Customer
{
public Guid Id { get; set; }
public List<Category> Categories { get; set; } ...
}
class Category
{
public Guid Id { get; set; }
public string Name { get; set; } ...
}
但是,当我创建一个新的客户实例但链接到预先存在的类别时,它变得有点不合适。在这种情况下,类别就像一个标签,因此几个客户将共享指向它的指针,每个新客户只需要重用已经存在的类别。 (如果类别的ID设置为唯一,我会收到已创建对象的错误,如果不是,则会得到重复。)
我知道它与EF引擎相关的对象状态有关。它根本不知道新客户中的类别已经存在于DB中,因此试图创建它。
我玩了状态并进入了一些复杂的算法,这会影响可读性。然后,我想出了以下方法。我实际上并没有对数据做任何事情 - 我只是把它拉到EF的客户端,让它意识到它们的存在。
List<Guid> ids = data.Categories
.Select(_ => _.Id).ToList();
List<Category> existing = Context.Categories
.Where(_ => ids.Contains(_.Id)).ToList();
为了简化,我们假设类别的数量是有限的,因此将检索重新制定为下面的代码。 (这基本上就像是说“嗯...说到类别......好吧,没关系。”,这似乎在学术上是错误的。)
List<Categories> _ = Context.Categories.ToList();
在这种情况下,是否建议采用最佳做法的模式或方法?
我意识到上面的示例只是Q&amp; D解决方法。提到的实体状态很复杂。我感觉有一种解决它的巧妙方法。
答案 0 :(得分:0)
您无需将所有现有类别加载到内存中。相反,只需将新客户与他拥有的现有类别相关联,方法是从上下文中加载它们。
Guid[] categoryIdsOfNewCustomer; // passed as part of the create command
var newCustomer = new Customer();
newCustomer.Categories = Context.Categories
.Where(c => categoryIdsOfNewCustomer.Contains(c.Id))
.ToList();
Context.Customers.Add(newCustomer);
Context.SaveChanges();