为什么在多关系中使用ICollection而不是IEnumerable或List <T>?

我在教程中看到了很多,导航属性为ICollection<T>

这是entity framework的强制性要求吗? 我可以使用IEnumerable吗?

使用ICollection代替IEnumerable甚至List<T>的主要目的是什么?

通常你select什么取决于你需要访问哪些方法。 一般来说 – IEnumerable<> (MSDN: http : //msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx )只需要迭代对象的列表, ICollection<> ( MSDN: http : //msdn.microsoft.com/en-us/library/92t2ye13.aspx )获取需要迭代和修改的对象列表, List<>获取需要迭代的对象列表,修改,sorting等(见这里的完整列表: http : //msdn.microsoft.com/en-us/library/6sh2ey19.aspx )。

从更具体的angular度来看,懒惰加载来selecttypes。 默认情况下,entity framework中的导航属性带有更改跟踪,并且是代理。 为了将dynamic代理创build为导航属性,虚拟types必须实现ICollection

表示关系“多”端的导航属性必须返回实现ICollection的types,其中T是关系另一端的对象types。 – 创buildPOCO代理MSDN的要求

有关定义和pipe理关系的更多信息MSDN

因为IEnumerable<T>接口不提供添加项目,删除项目或以其他方式修改集合的方法,所以使用ICollection<T>

回答关于List<T>

List<T>是一个类; 指定一个接口允许更多的实现灵活性。 更好的问题是“为什么不要IList<T>

要回答这个问题,考虑一下IList<T>加到ICollection<T> :整数索引,这意味着这些项目有一些任意的顺序,并且可以通过参考该顺序来检索。 这在大多数情况下可能没有意义,因为项目可能需要在不同的环境下以不同的顺序排列。

使用ICollection的基本思想是提供一个只读访问一些有限数量的数据的接口。 实际上你有一个ICollection.Count属性。 IEnumerable更适合于读取某些逻辑点的数据链,某些情况由消费者直接指定或直到枚举结束。

ICollection和IEnumerable之间有一些基本的区别

  • IEnumeration – 仅包含GetEnumerator方法来获取枚举器并进行循环
  • ICollection包含以下方法 – 添加/删除/包含/计数/ CopyTo
  • ICollection从IEnumerableinheritance
  • 通过使用ICollection,你可以使用添加/删除(Add / Remove)等方法来修改这个集合,但是你没有这个自由去做IEnumerable。

简单程序:

 using System; using System.Collections; using System.Collections.Generic; namespace StackDemo { class Program { static void Main(string[] args) { List<Person> persons = new List<Person>(); persons.Add(new Person("John",30)); persons.Add(new Person("Jack", 27)); ICollection<Person> personCollection = persons; IEnumerable<Person> personEnumeration = persons; //IEnumeration //IEnumration Contains only GetEnumerator method to get Enumerator and make a looping foreach (Person p in personEnumeration) { Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age); } //ICollection //ICollection Add/Remove/Contains/Count/CopyTo //ICollection is inherited from IEnumerable personCollection.Add(new Person("Tim", 10)); foreach (Person p in personCollection) { Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age); } Console.ReadLine(); } } class Person { public string Name { get; set; } public int Age { get; set; } public Person(string name,int age) { this.Name = name; this.Age = age; } } } 

我记得这样:

  1. IEnumerable有一个方法GetEnumerator(),它允许读取集合中的值但不写入它。 使用枚举数的大部分复杂性都由C#中的每个语句来处理。 IEnumerable有一个属性:Current,它返回当前元素。

  2. ICollection实现了IEnumerable,并增加了Count的最多用法。 ICollection的通用版本实现了Add()和Remove()方法。

  3. IList实现IEnumerable和ICollection。

导航属性通常被定义为虚拟的,以便他们可以利用某些entity frameworkfunction,例如延迟加载。

如果导航属性可以包含多个实体(如多对多或一对多关系),则其types必须是可以添加,删除和更新条目的列表,例如ICollection。

https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net- MVC应用程序

我过去所做的是使用IList<Class>ICollection<Class>IEnumerable<Class> (如果是静态列表)声明我的内部类集合,具体取决于是否需要在方法在我的资源库: 枚举,sorting/顺序或修改 。 当我只需要枚举(也许sorting)对象,然后创build一个临时List<Class>以在IEnumerable方法中使用集合。 我认为这种做法只会是有效的,如果收集是比较小的,但它可能是一般的良好做法,idk。 如果有证据表明这是不好的做法,请纠正我。