EF ICollection Vs List Vs IEnumerable Vs IQueryable

Lui*_*cia 47 c# entity-framework entity-framework-4 entity-framework-4.1

所以,我的EF模型有关系,根据我在例子中看到的,这些关系应该用ICollection的虚拟属性来完成.

例:

 public class Task
    {
        public int Id { get; set; }
        public string Description { get; set; }
        public virtual ICollection<SubTask>  { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

我在某处读到了我应该使用IEnumerable来防止延迟执行,这是正确的吗?这意味着如果我的DAL方法返回IEnumerable,仍然是IQueryable,那么SQL将在那一刻执行,而不是在我在网页中调用.TOList时.

那么,最佳做法是什么?我该怎么回事?IEnumerable,List?,IList,ICollection?

谢谢

Han*_*ing 64

IQueryable:

  • 在您真正迭代项目之前,不执行查询,可能是通过执行.ToList()或执行foreach.这意味着您仍然可以添加过滤器,例如Where().
  • 扩展IEnumerable

IEnumerable:

  • 仅向前的项目列表.如果没有传递0-3项,你就无法进入"第4项".
  • 只读列表,您无法添加或删除它.
  • 仍然可能使用延迟执行(IQueryable仍然是IEnumerable).

IList:

  • 随机访问完整列表
  • 可能完全在内存中(没有延迟执行,但是谁知道实现这个的确切类是什么?)
  • 支持添加和删除
  • 扩展IEnumerable和ICollection

ICollection:

  • 在IEnumerable和IList之间.
  • 扩展IEnumerable

什么是"最好"取决于您的要求.通常,如果您只想显示项目,IEnumerable"足够好".至少总是使用通用变体.

  • 很好的分解.至于延迟执行,直到你在IEnumerable上调用.GetEnumerator(其他类型都派生自)时才会形成查询.如果您使用IQueryable以外的任何其他内容,则所有结果都将发送到客户端并在那里进行过滤,而不是在数据库级别应用过滤器.您需要IQueryable来保留GetEnumerator将用于生成适当TSQL的表达式树. (4认同)
  • 如果将导航属性公开为IEnumerable <T>,则无法将项目添加到集合中. (3认同)
  • @Schultz9999 - 大多数 LINQ-to-Objects 方法适用于 IEnumerables,而不是 ILists。他们可能会在内部检查它是否也是 IList 或 ICollection 并为此使用优化的代码。另请参阅 Jon Skeet 的 [EduLinq](http://codeblog.jonskeet.uk/2010/12/26/reimplementing-linq-to-objects-part-7-count-and-longcount/) 系列。 (2认同)