0

新規ではないオブジェクト/エンティティのグラフを持つ新しいエンティティを追加しようとして問題が発生しました。

コードファーストアプローチを使用したドメインタイプは次のとおりです。

public class Person : IEntity
{
   public int Id { get; set; }
   public string Name { get; set; }
   public List<PersonSession> Sessions { get; set; }
}

 public class PersonSession : IEntity
 {
    public int Id { get; set; }
    public Person Person { get; set; }
    public Session Session { get; set; }
 }

public class Session : IEntity
{
  public int Id { get; set; }
  public string Title { get; set; }     
}

だから私には人がいて、彼らは多くのセッションを持つことができ、彼らのセッションのテーブルがあります。ただし、Sessionテーブルには、personへの参照はありません。これが、PersonSessionsテーブル/リレーションシップの目的です。

EF 5は、1つのDbSetを使用してこれらの3つのテーブルを作成します。

しかし、Genericsを使用して単純なリポジトリパターンを作成しようとしています。Saveメソッドがあります。

唯一の問題は、Repository.GetAll()によって与えられた既存のセッションを使用している場合でも、Sessionsテーブルに新しいセッションを追加することです。

 public int Save(T t)
 {
    if (t.Id == 0)
       _context.Entry(t).State = EntityState.Added;
    else
       _context.Entry(t).State = EntityState.Modified;

    _context.SaveChanges();
    return t.Id;
 }

したがって、2つの新しいセッションを作成し、それらをSessionsのGeneric Repoインスタンスを介して追加すると、正しく追加されます。

私が新しい人を作成して、そのような既存のセッションを彼に与えるとき:

  private static void AddPerson()
  {

     var newPerson = new Person
                        {
                           JobTitle = EJobTitle.SoftwareDeveloper,
                           Name = "Mark W",
                        };

     var sessionsForPerson = new List<PersonSession>();

     var session1 = _sessionRepo.Retrieve(1);
     var session2 = _sessionRepo.Retrieve(2);

     sessionsForPerson.Add(new PersonSession
                              {
                                 Session = session1,
                                 Person = newPerson
                              });

     sessionsForPerson.Add(new PersonSession
                              {
                                 Session = session2,
                                 Person = newPerson,
                              });

     newPerson.Sessions = sessionsForPerson;

     _personRepo.Save(newPerson);
  }

2回目のセッションの追加です。

PersonSession.Sessionプロパティに追加して、これが常に既存のセッションになることを通知できるデータ属性はありますか、それともFluentApiで何かを使用してEFに指示する必要がありますか?

ありがとう。

4

2 に答える 2

1

あなたのSaveメソッドでは、 new の状態を に設定しPersonますEntityState.Added。これを行うと、EF はオブジェクト グラフ内のオブジェクトの状態を に設定しますAddedSessionの ID がすでに 0 より大きいことは問題ではありません。これは、グラフ内のオブジェクトが以前に同じコンテキストによって取得されていない限りです。その場合、それらは変更されずに残ります (関連付けのみが保存されます)。

それが問題です。リポジトリにはそれぞれ独自のコンテキストがあります。これは、一般的なリポジトリでよくある問題です。考えられる解決策の 1 つは、リポジトリの外部にコンテキストを作成し、それを 1 つのビジネス トランザクションに関与するリポジトリに注入することです。もう 1 つの方法は、ルート エンティティを追加した後にオブジェクト グラフをトラバースすることにより、既存のオブジェクトが変更されていない状態でコンテキストに入るようにすることです。

于 2012-12-19T22:40:43.637 に答える
0

エンティティ キーであるプロパティを指定してみてください。

public class Person : IEntity
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public List<PersonSession> Sessions { get; set; }
}

 public class PersonSession : IEntity
 {
    [Key]
    public int Id { get; set; }
    public Person Person { get; set; }
    public Session Session { get; set; }
 }

public class Session : IEntity
{ 
    [Key]
    public int Id { get; set; }
    public string Title { get; set; }     
}
于 2012-12-19T21:46:53.530 に答える