2015-04-26 51 views
5

我正在使用Visual Studio自动构建代码的第一个模型NorthWind数据库。我有一些疑问。实体框架:为什么实体类的集合类型需要在默认构造函数中实例化?

  1. 我发现如果实体类有一个集合,那么该集合总是在默认构造函数中实例化。为什么我们需要这样做?

  2. ICollection<T>在默认构造函数中实例化为HashSet<T>。为什么使用HashSet<T>?我可以使用List<T>或其他东西吗?

  3. 为什么在一个侧(一对多关系)的导航属性是ICollection<T>virtual

要以我上面提到的方式实现实体类,我认为必须有一些好处可以带来。你能告诉我为什么吗?

public partial class Orders 
{ 
    public Orders() 
    { 
     Order_Details = new HashSet<Order_Details>(); 
    } 
    public virtual ICollection<Order_Details> Order_Details { get; set; } 
} 
+0

HashSet 是一个限制只包含唯一条目的集合,内部结构针对搜索进行了优化,而不是列表 - 它速度相当快。 –

+0

更快找到给定的对象实例,而不是通过Id属性查找某个内容。 –

回答

5

我发现,如果实体类有一个集合,则是集合始终处于默认的构造函数实例。为什么我们需要这样做?

你不知道。在开始向其添加东西之前,只需要实例化它。

ICollection实例化为默认构造函数中的HashSet。为什么使用HashSet?我可以使用List或其他东西吗?

您可以使用任何实现ICollection<T>作为具体实现。

为什么“one”方(一对多关系)的导航属性是ICollection并且是虚拟的?

ICollection<T>是EF期望用于导航属性的接口。它提供了表示该类型关系所需的最小界面。它是虚拟的,以便EF可以在运行时插入代理以检测对属性的更改。如果您决定不使其虚拟化,则需要手动通知EF有关该属性的更改。

+0

我认为重要的是要注意没有。 2,'HasSet'强制唯一性,而'List'可以重复。 – jwatts1980

+1

除非你重载'Equals'和'GetHashCode',equals意味着一个引用相等...完全相同的对象实例的两个副本。值得注意的是,你通常不会遇到有实际区别的情况(或者至少我不这样做)。 –

4

我发现如果实体类有一个集合,那么该集合总是在默认构造函数中实例化。为什么我们需要这样做?

出于同样的原因,你实例化你的类中的任何引用类型字段。当你第一次访问它时,它会被使用并且不会抛出NRE。

ICollection实例化为默认构造函数中的HashSet。为什么使用HashSet?我可以使用List或其他东西吗?

一个HashSet<T>使用,因为它保证两个值它们彼此相等(这是平等的看着他们GetHashCodeEquals方法检查)只集合中出现一次。 是的,您可以将具体类型更改为实现ICollection<T>的任何类型。

为什么“one”方(一对多关系)的导航属性是ICollection并且是虚拟的?

因为如果某个对象具有一对多关系,这意味着每个实例(一个)将具有不同类型(许多)的集合。允许EF在运行时注入代理是虚拟的。

+2

'使用HashSet 是因为它确保唯一值只会在集合中出现一次。它确保只有一次出现完全相同的对象实例(除非您覆盖Equals和GetHashCode)。如果将具有完全相同属性值的两个不同对象实例添加到散列集,则仍然会得到两个不同的条目。 –

+0

@Eric这就是我所追求的“独特价值”。我会澄清。 –

相关问题