在实体框架中使用hashset

时间:2012-06-21 04:45:04

标签: entity-framework

我想知道在构造函数中使用或不使用“hashset”创建类之间的区别。

使用代码优先方法(4.3)可以创建这样的模型:

public class Blog
 {
     public int Id { get; set; }
     public string Title { get; set; }
     public string BloggerName { get; set;}
     public virtual ICollection<Post> Posts { get; set; }
  }

public class Post
 {
    public int Id { get; set; }
    public string Title { get; set; }
    public DateTime DateCreated { get; set; }
    public string Content { get; set; }
    public int BlogId { get; set; }
    public ICollection<Comment> Comments { get; set; }
 }

或者可以创建这样的模型:

public class Customer
{
    public Customer()
    {
        BrokerageAccounts = new HashSet<BrokerageAccount>();
    }
    public int Id { get; set; }
    public string FirstName { get; set; }
    public ICollection<BrokerageAccount> BrokerageAccounts { get; set; }
}

public class BrokerageAccount
{

    public int Id { get; set; }
    public string AccountNumber { get; set; }
    public int CustomerId { get; set; }

}

什么是hashset在这里做什么?

我应该在前两个模型中使用hashset吗?

有没有文章显示hashset的应用?

3 个答案:

答案 0 :(得分:21)

一般来说,最好使用最能表达您意图的系列。如果您没有特别打算使用HashSet的独特特性,我就不会使用它。

它是无序的,不支持按索引查找。此外,它不像其他集合那样适合顺序读取,并且它允许您多次添加同一项而不创建重复项的事实仅在您有理由使用它时才有用。如果这不是你的意图,它可以隐藏行为不端的代码并使问题难以隔离。

HashSet主要用于插入和删除时间非常重要的情况,例如处理数据时。它对于使用intersect,except和union等操作来比较数据集(再次处理时)也非常有用。在任何其他情况下,缺点通常都超过专业人士。

考虑到使用博客帖子时,插入和删除与读取相比非常少见,并且您通常希望以特定顺序读取数据。这或多或少与HashSet擅长的完全相反。由于任何原因,您打算两次添加相同的帖子是非常值得怀疑的,我认为没有理由在类似的类中对帖子使用基于集合的操作。

答案 1 :(得分:18)

我对Entity Framework相当新,但这是我的理解。集合类型可以是实现ICollection<T>的任何类型。在我看来,HashSet通常是语义上正确的集合类型。大多数集合应该只有一个成员实例(没有重复),HashSet最好表达这一点。我一直在编写我的课程,如下所示,到目前为止一直运作良好。请注意,该集合的类型为ISet<T>,而setter是私有的。

public class Customer
{
    public Customer()
    {
        BrokerageAccounts = new HashSet<BrokerageAccount>();
    }
    public int Id { get; set; }
    public string FirstName { get; set; }
    public ISet<BrokerageAccount> BrokerageAccounts { get; private set; }
}

答案 2 :(得分:17)

HashSet不定义实际获取数据时将生成的集合类型。这将始终是声明的ICollection类型。

在构造函数中创建的HashSet是为了帮助您在没有记录被提取或存在于关系的多个方面时避免NullReferenceExceptions。这绝不是必需的。

例如,根据您的问题,当您尝试使用类似...的关系时

var myCollection = Blog.Posts();

如果没有帖子,则myCollection将为null。哪个是好的,直到你流畅地连锁并做一些像

这样的事情
var myCollectionCount = Blog.Posts.Count();

NullReferenceException会出错。

在哪里

var myCollection = Customer.BrokerageAccounts();
var myCollectionCount = Customer.BrokerageAccounts.Count();

将导致并清空ICollection和零计数。没有例外: - )