在 Code First EF 中声明 List 而不是 ICollection 有什么影响?

What's the effect of declaring List instead of ICollection in Code First EF?

通常,当我声明一对多关系时,我会使用 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; }
}

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

我的实际问题是,除了现在急切填充的列表之外,还有哪些内容会发生变化。

将您的 属性 声明为 ICollection<T>List<T> 与延迟加载没有任何共同之处 - 它是 virtual 修饰符控制您的 属性 是否可以懒加载与否

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

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

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

并检查 Things 成员的实际类型。您会看到它是 HashSet<Thing>,而不是 List<Thing>