42

コンストラクターで「ハッシュセット」を使用する場合と使用しない場合のクラスの作成の違いを知りたいです。

コード ファースト アプローチ (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; }

}

ハッシュセットはここで何をしていますか?

最初の 2 つのモデルでもハッシュセットを使用する必要がありますか?

ハッシュセットの適用を示す記事はありますか?

4

3 に答える 3

26

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 が空になり、カウントがゼロになります。例外なく :-)

于 2014-07-30T12:18:07.443 に答える
26

一般的に言えば、あなたの意図を最もよく表しているコレクションを使用するのが最善です。HashSet の独自の特性を特に使用するつもりがない場合は、使用しません。

これは順序付けされておらず、インデックスによる検索をサポートしていません。さらに、他のコレクションほど順次読み取りには適していません。重複を作成せずに同じアイテムを複数回追加できるという事実は、そのために使用する理由がある場合にのみ役立ちます。それがあなたの意図ではない場合、不正な動作をするコードが隠され、問題の切り分けが難しくなる可能性があります。

HashSet は、データを処理するときなど、挿入と削除の時間が非常に重要な状況で最も役立ちます。また、intersect、except、union などの操作を使用してデータのセットを比較する場合にも非常に役立ちます (処理時)。他の状況では、一般に短所が長所を上回ります。

ブログの投稿を操作する場合、挿入と削除は読み取りに比べて非常にまれであり、とにかく特定の順序でデータを読み取る必要があることを考慮してください。これは、HashSet が得意とすることとほぼ正反対です。なんらかの理由で、同じ投稿を 2 回追加するつもりがあるかどうかは非常に疑わしく、そのようなクラスの投稿でセットベースの操作を使用する理由はわかりません。

于 2013-08-10T05:22:51.100 に答える
21

私はEntityFrameworkにかなり慣れていませんが、これは私の理解です。コレクションタイプは、を実装する任意のタイプにすることができますICollection<T>。私の意見では、HashSetは通常意味的に正しいコレクションタイプです。ほとんどのコレクションには、メンバーのインスタンスが1つだけ含まれている必要があり(重複はありません)、HashSetはこれを最もよく表現します。私は以下のようにクラスを書いていますが、これは今のところうまくいきました。コレクションはとして入力されISet<T>、セッターはプライベートであることに注意してください。

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; }
}
于 2013-03-15T13:11:37.547 に答える