为什么我需要多对多关系中的HashSet?

时间:2016-10-07 07:17:14

标签: asp.net asp.net-mvc many-to-many

我找到了许多使用HashSet ex

的教程
this.Supplier = new HashSet<supplier>();

在多对多的关系中。但是som教程使用下面的代码而没有HashSet(不多或少)

public partial class Product
{
    public Product()
    {
        this.Supplier = new HashSet<supplier>();
    }

    public long ProductID { get; set; }
    public string ProductName { get; set; }

    //navigation property to Supplier
    public virtual ICollection<supplier> Supplier { get; set; }
}

public partial class Supplier
{
    public Supplier()
    {
        this.Product = new HashSet<product>();
    }

    public long SupplierID { get; set; }
    public string SupplierName { get; set; }

    // navigation property to Product
    public virtual ICollection<product> Product { get; set; }
}

当我测试上面的代码并删除

    public xxxx()
    {
        this.xxxx = new HashSet<xxxx>();
    }

我仍然有一个关联表和多对多的关系。

为什么我需要HashSet?

1 个答案:

答案 0 :(得分:3)

通常在两个表模型中使用ICollection定义多对多关系:

public virtual ICollection<supplier> Supplier { get; set; }

public virtual ICollection<product> Product { get; set; }

模型上ICollection的存在意味着启用了延迟加载,允许EF为它们创建派生类。

关于在模型世代中使用HashSet,ChrisV在HashSet in EF many to many中说:

  

HashSet实现了一个非常有效的哈希表   操作,例如在大型集合中搜索单个项目。

默认情况下HashSet的使用主要基于效率原因以及非空值,例如Yuval Itzchakov在Entity Framework:Why the collection type of entity class need to be instanced in the default constructor?中说:

  

使用HashSet是因为它保证了两个值   彼此相等(通过查看它们来检查相等性   GetHashCode和Equals方法)仅在集合中出现一次。   是的,您可以将具体类型更改为任何实现的类型   ICollection<T>

上面的解释可以概括为“HashSet是模型构造函数中ICollection接口的初始化步骤,它保证了每个相关模型成员之间的相等性”。 EF本身并不关心应该在ICollection上为表模型应用哪些实现,您可以在构造函数中使用List<T>替换HashSet<T>,并且多对多关系仍然不会受到影响。

在模板模型(.tt文件)中,默认情况下,您可能会看到这些行生成HashSet<T>,因为它实现了ICollection

foreach (var navigationProperty in collectionNavigationProperties)
{
#>
   this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
<#
}

您可以通过在重新生成模型时删除或更改HashSet<T>初始化来进行实验,但是我认为将其删除以进行大量数据操作并不是一个好习惯。