实体框架中的ICollection <T>与List <T>


114

在开始设计一些Entity Framework应用程序之前,我仅观看了一些网络广播。我确实没有读那么多文档,所以我现在为此感到痛苦。

List<T>在课堂上一直在使用,效果很好。

现在,我已经阅读了一些文档,并指出我应该一直在使用ICollection<T>。我改成了这个,它甚至没有引起模型上下文的改变。这是因为List<T>ICollection<T>都继承了IEnumerable<T>,而这正是EF实际需要的吗?

但是,如果是这种情况,为什么EF文档没有声明它需要它IEnumerable<T>而不是ICollection<T>

无论如何,我做过的事情有什么弊端,还是我应该改变它?

Answers:


113

ICollection<T>之所以会使用实体框架,是因为它需要支持Add不属于IEnumerable<T>接口一部分的操作。

另请注意,您使用ICollection<T>,只是将其作为List<T>实现公开。List<T>随之带来的IList<T>ICollection<T>IEnumerable<T>

至于您所做的更改,尽管可行,但通过界面进行公开是一个不错的选择List<T>。该接口定义合同,但不定义实现。实现可能会改变。例如,在某些情况下,实现可能是HashSet<T>。(顺便说一下,(这是一种思维方式,您不仅可以用于实体框架。)一种好的面向对象的实践是针对接口而不是实现进行编程。实现可能并且将会改变。)


2
所以....只是让我进一步了解-列表继承了IList,继承了ICollection,它继承了IEnumerable?
WIL

3
是的,那就是连锁店。List<T>具有实现每个接口(的IList<T>ICollection<T>IEnumerable<T>因为继承层次的)。对于完成后,IList<T>还拿起非泛型IListICollectionIEnumerable接口。
安东尼·佩格拉姆

谢谢...某些Ixxx功能仍然无法理解!但是,您已经知道,让我烦恼的最后一件事是,如果另一个Ixx继承了IEnumerable,那么如果Ienumerable是只读的,它将如何添加到IEnumerable中?...如果太复杂,不用担心,如果我有一点时间,我将尝试启动反射器!
WIL

10
正常的Linq操作不会添加或变异内容,它们只是过滤,分组,项目等。仅向前,只读序列是支持这些操作所必需的。当您拥有诸如Entity Framework之类的处理数据持久性的Linq提供程序时,添加功能是一项实质性的好处,需要一个更强大的界面,这才是邀请ICollection<T>聚会的原因(并且该界面也随之而来IEnumerable<T>,因此“正常” “ Linq操作仍然有效)。
安东尼·佩格拉姆

@AnthonyPegram:我认为说所有三个接口都必须实现是完全错误的。由于IList <T>继承了ICollection <T>,而ICollection <T>继承了IEnumerable <T>,因此List <T>只需实现IList <T>就足够了。
CJ7 '12

51

他们选择了他们做的接口,因为它为使用Linq时实体框架执行的魔术查询提供了可理解的抽象。

这是接口之间的区别:

  • IEnumerable<T> 是只读的
  • 您可以添加和删除项目到 ICollection<T>
  • 您可以随机访问(按索引) List<T>

出者,ICollectionIEnumerable很好地映射到数据库的操作,因为查询和添加/删除实体的东西,你可能会在DB做。

按索引的随机访问也不会映射,因为您必须有一个现有的查询结果才能进行迭代,否则每次随机访问都会再次查询数据库。另外,索引将映射到什么?行号?您不需要执行很多行号查询,并且在建立更大的查询时根本没有用。因此,他们根本不支持它。

ICollection<T> 支持,并且将允许您查询和更改数据,因此可以使用它。

之所以List<T>开始工作,是因为EF实现最终返回了一个。但这只是查询链的末尾,而不是开始。因此,对属性ICollection<T>进行设置将使EF明显创建一堆SQL,并且仅List<T>在末尾返回a ,而不是对您使用的每个Linq级别进行查询,这一点更加明显。


8

ICollection与IEnumerable的不同之处在于,您实际上可以向集合中添加项目,而IEnumerable则不能。因此,例如,在POCO类中,如果打算允许将集合添加到其中,则希望使用ICollection。将ICollection虚拟化也可以从延迟加载中受益。


1
我想了解-您可以使用List <T>进行相同的操作(甚至更多!)。为什么选择ICollection <T>?为什么不列出<T>?看起来更简单,功能更强大。
monstro

List <T>实现ICollection和IEnumerable。更多的操作,但随之而来的是更多的开销。
IronAces

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.