简体   繁体   English

我收藏<t>与清单<t>在实体框架中</t></t>

[英]ICollection<T> Vs List<T> in Entity Framework

I only watched a few webcasts before I went head first in to designing a few Entity Framework applications.在我开始设计一些 Entity Framework 应用程序之前,我只看了几个网络广播。 I really didn't read that much documentation and I feel like I am suffering for it now.我真的没有读那么多文档,我觉得我现在正在为此受苦。

I have been using List<T> in my classes, and it has worked great.我一直在课堂上使用List<T> ,效果很好。

Now I have read some documentation and it states that I should have been using ICollection<T> .现在我已经阅读了一些文档,它指出我应该一直在使用ICollection<T> I changed to this, and it didn't even cause a model context change.我改成了这个,它甚至没有导致 model 上下文更改。 Is this because both List<T> and ICollection<T> inherit IEnumerable<T> , and that is what is actually required for EF?这是因为List<T>ICollection<T>都继承了IEnumerable<T> ,而这正是 EF 实际需要的吗?

However, if this is the case, why doesn't the EF documentation state that it requires IEnumerable<T> instead of ICollection<T> ?但是,如果是这种情况,为什么 EF 文档 state 不需要IEnumerable<T>而不是ICollection<T>

Entity Framework would use ICollection<T> because it needs to support Add operations, which are not part of the IEnumerable<T> interface. 实体框架将使用ICollection<T>因为它需要支持Add操作,这些操作不属于IEnumerable<T>接口。

Also note that you were using ICollection<T> , you were merely exposing it as the List<T> implementation. 另外请注意,您使用ICollection<T>你只是暴露它的List<T>的实施。 List<T> brings along with it IList<T> , ICollection<T> , and IEnumerable<T> . List<T>带来IList<T>ICollection<T>IEnumerable<T>

As for your change, exposing via the interface is a good choice, despite List<T> working. 至于你的改变,尽管List<T>工作,通过界面公开是一个不错的选择。 The interface defines the contract but not the implementation. 接口定义合同但不定义实现。 The implementation could change. 实施可能会改变。 In some instances, perhaps the implementation could be a HashSet<T> , for example. 在某些情况下,例如,实现可能是HashSet<T> (This is a mindset you could use for more than just Entity Framework, by the way. A good object-oriented practice is to program towards the interface and not the implementation. Implementations can and will change.) (顺便说一句,这是一种不仅仅是实体框架可以使用的思维模式。良好的面向对象实践是针对接口而不是实现进行编程。实现可以并且将会改变。)

They picked the interface they did because it gives a comprehensible abstraction over the magic queries the Entity Framework performs when you use Linq. 他们选择了他们所做的界面,因为它为您在使用Linq时实体框架执行的魔术查询提供了可理解的抽象。

Here's the difference between the interfaces: 这是接口之间的区别:

  • IEnumerable<T> is read-only IEnumerable<T>是只读的
  • You can add and remove items to an ICollection<T> 您可以在ICollection<T>添加和删​​除项目
  • You can do random access (by index) to a List<T> 您可以对List<T>进行随机访问(通过索引)

Out of those, ICollection and IEnumerable map well to database operations, since querying and adding/removing entities are things you might do in a DB. 其中, ICollectionIEnumerable很好地映射到数据库操作,因为查询和添加/删除实体是您可能在数据库中执行的操作。

Random access by index doesn't map as well, since you'd have to have an existing query result to iterate over, or each random access would query the database again. 索引的随机访问也不会映射,因为您必须有现有的查询结果进行迭代,或者每次随机访问都会再次查询数据库。 Also, what would the index map to? 此外,索引将映射到什么? Row number? 行号? There aren't a lot of row number queries you'd want to do, and it isn't useful at all in building up bigger queries. 您不想进行大量的行号查询,并且在构建更大的查询时根本没用。 So they simply don't support it. 所以他们根本就不支持它。

ICollection<T> is supported, and will allow you to both query and change data, so use that. 支持ICollection<T> ,并允许您查询和更改数据,因此请使用它。

The reason List<T> works to begin with is because the EF implementation ends up returning one in the end. List<T>开始工作的原因是因为EF实现最终会返回一个。 But that's at the end of your query chain, not at the beginning. 但这是在您的查询链的末尾,而不是在开头。 So making your properties ICollection<T> will make it more obvious that the EF creates a bunch of SQL and only returns a List<T> at the end, rather than doing queries for each level of Linq that you use. 因此,使您的属性ICollection<T>将使EF更明显地创建一堆SQL并且最后只返回List<T> ,而不是对您使用的每个级别的Linq进行查询。

ICollection differs from IEnumerable in that you can actually add items to the collection, whereas with IEnumerable you can't. ICollection与IEnumerable的不同之处在于您实际上可以将项添加到集合中,而使用IEnumerable则不能。 So in your POCO classes, for instance, you want to use ICollection if you intend to allow the collection to be added to. 例如,在您的POCO类中,如果您打算允许添加集合,则需要使用ICollection。 Make the ICollection virtual to benefit from lazy loading too. 使ICollection虚拟也可以从延迟加载中受益。

Although the question has been posted years back, its still valid when someone is looking for the same scenario. 虽然这个问题已在几年前发布,但当有人正在寻找相同的场景时,它仍然有效。

There is a recent [2015] CodeProject article which explains the difference in much detail and graphical representation with sample code . 最近[2015] CodeProject文章用样本代码解释了细节和图形表示的差异。 It is not focused directly at EF but still hope it will be of greater help: 它没有直接关注EF,但仍然希望它会有更大的帮助:

List vs IEnumerable vs IQueryable vs ICollection vs IDictionary List vs IEnumerable vs IQueryable vs ICollection vs IDictionary

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM