我在教程中经常看到这种情况,导航属性为ICollection<T>。
这是实体框架的强制性要求吗?我可以使用IEnumerable吗?
使用ICollection而不是IEnumerable或List<T>的主要目的是什么?
我在教程中经常看到这种情况,导航属性为ICollection<T>。
这是实体框架的强制性要求吗?我可以使用IEnumerable吗?
使用ICollection而不是IEnumerable或List<T>的主要目的是什么?
使用ICollection的基本思想是提供一个接口来快速访问有限数量的数据。事实上,你有一个收藏。数属性。IEnumerable更适合于某些数据链,在这些数据链中,你可以读到某个逻辑点,某个消费者特别指定的条件,或者读到枚举的结尾。
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创建要求
关于定义和管理关系的更多信息
回复你关于List<T>的问题:
List<T>是一个类;指定接口可以使实现更加灵活。一个更好的问题是“为什么不IList<T>?”
要回答这个问题,请考虑IList<T>向ICollection<T>:整数索引添加了什么,这意味着项具有某种任意顺序,并且可以通过引用该顺序来检索。这在大多数情况下可能没有意义,因为项目可能需要在不同的上下文中以不同的顺序排列。
What I have done in the past is declare my inner class collections using IList<Class>, ICollection<Class>or IEnumerable<Class> (if static list) depending on whether or not I will have to do any number of the following in a method in my repository: enumerate, sort/order or modify. When I just need to enumerate (and maybe sort) over objects then I create a temp List<Class>to work with the collection within an IEnumerable method. I think this practice would only be effective if the collection is relatively small, but it may be good practice in general, idk. Please correct me if there is evidence as to why this would not good practice.
我是这样记得的:
IEnumerable has one method GetEnumerator() which allows one to read through the values in a collection but not write to it. Most of the complexity of using the enumerator is taken care of for us by the for each statement in C#. IEnumerable has one property: Current, which returns the current element. ICollection implements IEnumerable and adds few additional properties the most use of which is Count. The generic version of ICollection implements the Add() and Remove() methods. IList implements both IEnumerable and ICollection, and add the integer indexing access to items (which is not usually required, as ordering is done in database).
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
让我们试着跳出逻辑思维的框框,清楚地理解你问题中的这三个接口:
当某个实例的类实现了System.Collection.IEnumerable接口时,简单地说,我们可以说这个实例既是可枚举的又是可迭代的,这意味着这个实例允许以某种方式在一个循环中遍历/获取/传递/遍历/遍历这个实例包含的所有项和元素。
这意味着也可以枚举此实例包含的所有项和元素。
每个实现System.Collection.IEnumerable接口的类都实现了GetEnumerator方法,该方法不接受参数并返回System.Collections.IEnumerator实例。
System.Collections.IEnumerator接口的实例的行为非常类似于c++的迭代器。
当某个实例的类实现了System.Collection.ICollection接口时,简单地说,我们可以说这个实例是一些东西的集合。
此接口的通用版本,即System.Collection.Generic。ICollection的信息更丰富,因为这个泛型接口显式地声明了集合中事物的类型。
这一切都是合理的,合理的,合乎逻辑的,而且System.Collections.ICollection接口继承自System.Collections.IEnumerable接口,因为理论上每个集合都是可枚举的和可迭代的,理论上可以遍历每个集合中的所有项和元素。
icollection接口表示一个可变的有限动态集合,这意味着现有的项可以从集合中删除,新项可以添加到同一个集合中。
这就解释了为什么System.Collections.ICollection接口有“添加”和“删除”方法。
因为System.Collections.ICollection接口的实例是有限的集合,所以“有限”这个词意味着这个接口的每个集合总是有有限数量的项和元素。
System.Collections.ICollection接口的属性Count应该返回这个数字。
System.Collections.IEnumerable接口不具有System.Collections.ICollection接口所具有的这些方法和属性,因为System.Collections.IEnumerable接口具有System.Collections.ICollection接口所具有的这些方法和属性没有任何意义。
该逻辑还表明,并非所有既可枚举又可迭代的实例都是必要的 一个集合,不一定是可变的。
我说的可更改,是指不要马上认为你可以从可枚举和可迭代的东西中添加或删除一些东西。
If I just created some finite sequence of prime numbers, for example, this finite sequence of prime numbers is indeed an instance of System.Collections.IEnumerable interface, because now I can go over all the prime numbers in this finite sequence in a single loop and do whatever I want to do with each of them, like printing each of them to the console window or screen, but this finite sequence of prime numbers is not an instance of System.Collections.ICollection interface, because this is not making sense to add composite numbers to this finite sequence of prime numbers.
另外,您还希望在下一个迭代中获得下一个与当前迭代中的当前素数最接近的大素数,如果这样的话,您也不想从这个有限的素数序列中删除现有的素数。
此外,您可能还想在system . collections . ienumerable接口的GetEnumerator方法中使用、编码和编写“yield return”来生成质数,并且不在内存堆上分配任何东西,然后让垃圾收集器(GC)从堆中释放和释放这些内存,因为这显然是浪费操作系统内存并降低性能。
当调用System.Collections.ICollection接口的方法和属性时,应该在堆上进行动态内存分配和回收,而不是在调用System.Collections.IEnumerable接口的方法和属性时(尽管System.Collections.IEnumerable接口只有1个方法和0个属性)。
根据其他人在Stack Overflow网页中所说的,System.Collections.IList接口只是代表了一个可排序的集合,这解释了为什么System.Collections.IList接口的方法与System.Collections.ICollection接口的方法不同。
简而言之,System.Collections.ICollection接口并不暗示它的实例是可排序的,但System.Collections.IList接口暗示了这一点。
理论上有序集是无序集的特殊情况。
这也解释了为什么System.Collections.IList接口继承了System.Collections.ICollection接口。