2011-03-22 11 views
4

に多くを保存します。私はこのような何かで作成された会社に現在のユーザーを追加したいと思います。Entity Frameworkのコードファーストは、私は2つのクラスを持っている多くの関係

User user = GetCurrentLoggedUser(); 
//company.Users = new ICollection<User>(); // Users is null :/ 
company.Users.Add(user); // NullReferenceException 
companyRepository.InsertOrUpdate(company); 
companyRepository.Save(); 

正しく動作させるにはどうすればいいですか?まだ分​​かりませんが、コレクションにユーザーを追加した後、データベースに保存する際に問題が生じることが予想されます。どのように見えるべきかについてのヒントは高く評価されます。

答えて

6

は、このアプローチを使用します。また、あなたのエンティティでEqualsGetHashCodeをオーバーライドする場合

public class Company 
{ 
    public int Id { get; set; } 
    public string Name { get; set;} 

    private ICollection<User> _users; 
    public ICollection<User> Users 
    { 
     get 
     { 
      return _users ?? (_users = new HashSet<User>()); 
     } 
     set 
     { 
      _users = value; 
     } 
    } 
} 

HashSetは、他のコレクションその後、より良いです。それはあなたの重複を処理します。また、遅延コレクションの初期化が優れています。私はそれを正確に覚えていませんが、コンストラクタでコレクションを初期化し、遅延ロードと変更追跡のために動的プロキシを使用したとき、最初のEFテストアプリケーションで問題が発生したと思います。

エンティティには、分離型と添付型の2種類があります。添付されたエンティティは既にコンテキストによって追跡されています。あなたは通常、linq-to-entitiesクエリから、またはDbSetCreateを呼び出して、添付されたエンティティを取得します。分離されたエンティティはコンテキストによって追跡されませんが、このエンティティを添付するためにAttachまたはAddをコールすると、関連するすべてのエンティティが追加/追加されます。分離されたエンティティで作業するときに対処する必要がある唯一の問題は、関連するエンティティがすでにデータベースに存在し、新しい関係を作成することだけであるということです。

あなたが理解しなければならない主なルールは追加して、取り付け方法の違いです:Added =>すべての関連企業が新しいものとして挿入されるように

  • Addは、グラフ内のすべてのデタッチのエンティティを添付します。
  • Attachグラフ内のすべての分離エンティティは、Unchanged =>変更されたものを手動で言う必要があります。あなたは通常、代わりにduplicitエンティティを挿入するだけで関係を構築するためにこれらの技術を使用する必要がありますデタッチ多対多で作業する場合

    context.Entry<TEntity>(entity).State = EntityState....; 
    

    を:あなたは手動で使用して取り付けられているすべてのエンティティの状態を設定することができ

データベース。

デタッチしたエンティティグラフを使用している私自身の経験では、特にリレーションを削除した後では、データベースからエンティティグラフを読み込み、手動ですべての変更を完全に追跡できる添付グラフに変更をマージします。

異なるコンテキストのエンティティを混在させることはできません。あるコンテキストから別のコンテキストにエンティティをアタッチする場合は、最初にエンティティを明示的にデタッチする必要があります。最初の文脈で、状態をDetachedに設定することでそれができることを願っています。

+0

この瞬間、私はHashSetとCollection(私はHashSetを選んでいます)との違いはあまりありません。あなたは私の文脈をどのように管理するのかを理解する助けになります。ユーザーを取得する前にCompanyRepositoryのコンテキストをUserRepositoryに設定しました。これは私に迅速なworkigソリューションを与える。本当にありがとうございます。 – bizon

2

Companyエンティティのコンストラクタでは、Usersプロパティに空のコレクションを作成できます。

public class Company 
{ 
    public Company() { 
     Users = new Collection<User>(); 
    } 

    public int Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<User> Users { get; set; } 
} 

限り、データベースに保存すると懸念しているとして、私は数日前に、関連する質問をし、Entity Frameworkのは、関連するエンティティに加えられた変更を追跡することが可能であることを保証しました。ここでその上に読む:

Are child entities automatically tracked when added to a parent?

+0

ご回答ありがとうございます。別のリポジトリからロードされたUserを追加すると、エラーが発生します。 'エンティティオブジェクトはIEntityChangeTrackerの複数インスタンスで参照できません。'あなたの質問のような変更後。すべてが問題ありませんが、データベースに別のユーザーが作成され、指定されたIDは使用されません。 ユーザーユーザー=新しいUserRepository()。GetByEmail(User.Identity.Name); \t \t \t \t company.Users.Add(新しいユーザー{Id = user.Id、FirstName = user.FirstName、LastName = user.LastName、Email = user.Email}); \t \t \t \t companyRepository.InsertOrUpdate(company); \t \t \t \t companyRepository.Save(); – bizon

関連する問題