ICollection <t>实体框架中的Vs List <t> </t> </t>

时间:2011-10-05 01:33:23

标签: c# list ef-code-first ienumerable icollection

在我首先设计一些Entity Framework应用程序之前,我只看了几个网络广播。我真的没有阅读那么多文档,我觉得我现在正在为它而痛苦。

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

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

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

在任何情况下,我所做的事情是否有任何缺点,或者我应该改变它?

4 个答案:

答案 0 :(得分:93)

实体框架将使用ICollection<T>,因为它需要支持Add操作,这些操作不属于IEnumerable<T>界面。

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

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

答案 1 :(得分:46)

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

这是接口之间的区别:

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

其中,ICollectionIEnumerable可以很好地映射到数据库操作,因为查询和添加/删除实体是您可能在数据库中执行的操作。

索引的随机访问也不会映射,因为您必须有一个现有的查询结果来迭代,或者每次随机访问都会再次查询数据库。此外,索引将映射到什么?行号?您不想进行大量的行号查询,并且在构建更大的查询时根本没用。所以他们根本就不支持它。

支持

ICollection<T>,并允许您查询和更改数据,因此请使用它。

List<T>开始使用的原因是因为EF实现最终会返回一个。但这是在您的查询链的末尾,而不是在开头。因此,使您的属性ICollection<T>更加明显,EF会创建一堆SQL,并且最后只返回List<T>,而不是对您使用的每个级别的Linq进行查询。

答案 2 :(得分:8)

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

答案 3 :(得分:3)

虽然这个问题已在几年前发布,但当有人正在寻找相同的情景时,它仍然有效。

最近[2015] CodeProject文章用示例代码解释了细节和图形表示的差异。它没有直接关注EF,但仍然希望它会有更大的帮助:

List vs IEnumerable vs IQueryable vs ICollection vs IDictionary