我在教程中经常看到这种情况,导航属性为ICollection<T>。

这是实体框架的强制性要求吗?我可以使用IEnumerable吗?

使用ICollection而不是IEnumerable或List<T>的主要目的是什么?


当前回答

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

IEnumerable -仅包含获取枚举器的GetEnumerator方法,并允许循环 ICollection包含其他方法:添加,删除,包含,计数,CopyTo ICollection继承自IEnumerable 使用ICollection,您可以使用添加/删除等方法修改集合。你不能自由地对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;
        }
    }
}

其他回答

导航属性通常被定义为虚拟的,这样它们就可以利用某些实体框架的功能,比如延迟加载。

如果一个导航属性可以保存多个实体(如在多对多或一对多关系中),那么它的类型必须是一个列表,其中可以添加、删除和更新条目,例如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-application

Usually what you choose will depend on which methods you need access to. In general - IEnumerable<> (MSDN: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx) for a list of objects that only needs to be iterated through, ICollection<> (MSDN: http://msdn.microsoft.com/en-us/library/92t2ye13.aspx) for a list of objects that needs to be iterated through and modified, List<> for a list of objects that needs to be iterated through, modified, sorted, etc (See here for a full list: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx).

从更具体的角度来看,延迟加载用于选择类型。默认情况下,实体框架中的导航属性带有更改跟踪,并且是代理。为了将动态代理创建为导航属性,虚拟类型必须实现ICollection。

表示关系的“多”端的导航属性必须返回实现ICollection的类型,其中T是关系另一端对象的类型。- POCO代理msdn创建要求

关于定义和管理关系的更多信息

使用ICollection的基本思想是提供一个接口来快速访问有限数量的数据。事实上,你有一个收藏。数属性。IEnumerable更适合于某些数据链,在这些数据链中,你可以读到某个逻辑点,某个消费者特别指定的条件,或者读到枚举的结尾。

回复你关于List<T>的问题:

List<T>是一个类;指定接口可以使实现更加灵活。一个更好的问题是“为什么不IList<T>?”

要回答这个问题,请考虑IList<T>向ICollection<T>:整数索引添加了什么,这意味着项具有某种任意顺序,并且可以通过引用该顺序来检索。这在大多数情况下可能没有意义,因为项目可能需要在不同的上下文中以不同的顺序排列。

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

IEnumerable -仅包含获取枚举器的GetEnumerator方法,并允许循环 ICollection包含其他方法:添加,删除,包含,计数,CopyTo ICollection继承自IEnumerable 使用ICollection,您可以使用添加/删除等方法修改集合。你不能自由地对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;
        }
    }
}