【问题标题】:What's the effect of declaring List instead of ICollection in Code First EF?在 Code First EF 中声明 List 而不是 ICollection 有什么影响?
【发布时间】:2016-07-16 00:38:19
【问题描述】:

通常,当我声明一对多关系时,我会使用 ICollection,如下所示。

public class Thong
{
  public Guid Id { get; set; }
  public ICollection<Thing> Things { get; set; }
}

public class Thing
{
  public Guid Id { get; set; }
  public Thong Thong { get; set; }
}

这是自动完成的,无需考虑假设等。然而,我现在开始思考,我真的无法判断接下来的改动会在设置中发生什么变化。我已经对其进行了迁移,但据我所知,数据库没有区别。

model.Entity<Thing>()
  .HasRequired(_ => _.Thong)
  .WithMany(_ => _.Things)
  .Map(_ => _.MapKey("ThongId"));

public class Thong
{
  public Guid Id { get; set; }
  public List<Thing> Things { get; set; }
}

public class Thing
{
  public Guid Id { get; set; }
  public Thong Thong { get; set; }
}

我怀疑的一件事是我刚刚终止了延迟加载,因此每次检索丁字裤时都会提供相关事物的所有实例。是这样吗?我很确定它是。

我的实际问题是,除了现在急切地填充列表之外,还有什么变化。

【问题讨论】:

  • 我认为如果您启用了更改跟踪,它不会有任何区别,实体框架将替换为 EntityCollection

标签: c# entity-framework ef-code-first ef-fluent-api


【解决方案1】:

将您的属性声明为ICollection&lt;T&gt;List&lt;T&gt; 与延迟加载没有任何共同之处——它是virtual 修饰符控制您的属性是否可以延迟加载。

不同之处在于,通过将属性声明为 List&lt;T&gt;,您将在加载实体时强制 EF 创建和填充 具体 类(或从该具体类派生的类) (懒惰或急切)。当声明为ICollection&lt;T&gt; 时,EF 可以使用一些内部数据结构填充它,T[]HashSet&lt;T&gt; 等,即实现ICollection&lt;T&gt; 的任何类。

例如,将您的变体与 ICollection 一起使用,尝试这样的操作

var result = db.Thong.Include(thong => thong.Things).ToList();

并检查Things 成员的实际类型。你会看到它是HashSet&lt;Thing&gt;,而不是List&lt;Thing&gt;

【讨论】:

  • 除此之外,人们可能更喜欢明确声明List&lt;T&gt;,因为更丰富的API(如AddRangeInsert、...)更适合特定的业务逻辑。
  • @GertArnold 沿着这些思路我开始考虑它,但拒绝了与潜在的 oopsies 和陷阱相比太弱的优势,因为据我所知,没有其他人这样做。
  • @KonradViltersten 不,我不提倡这样做。如果我需要一个特定的集合实现,我会设置一个视图或域模型。不过对其他人来说,这可能是一个可行的选择。
猜你喜欢
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 1970-01-01
  • 2011-09-11
  • 1970-01-01
相关资源
最近更新 更多