在LINQ for EF

时间:2018-06-14 13:42:49

标签: c# entity-framework linq asp.net-core

我注意到当我存储具有属性为另一种类型的对象时,它会被保存,但链接的属性也是如此。当两者都是新的或两者都在更新时,它都很整洁。

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解决方法。提到的实体状态很复杂。我感觉有一种解决它的巧妙方法。

1 个答案:

答案 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();