11

私は C# から始めて、独自の DB を作成したいと考えていました。

私は2つのモデルを持っています

public class AModel 
{
    public Guid ID { get; private set; }
    public string Name { get; set; }
    public int Count { get; set; }
    public AModel()
    {
        this.ID = Guid.NewGuid();
    }
}

public class BModel 
{
    public Guid ID { get; private set; }
    public string Name { get; set; }
    public AModel Model { get; set; }
    public BModel()
    {
        this.ID = Guid.NewGuid();
    }
}

BModel を DB に保存しようとすると、次のエラーが発生します。

PRIMARY KEY 制約 'PK_dbo.AModels' に違反しています。オブジェクト 'dbo.AModels' に重複するキーを挿入できません。重複するキーの値は (48ee1711-8da4-46c1-a714-19e985211fed) です。\r\nステートメントは終了しました。

これで解決かと思った

modelBuilder.Entity<BModel>().HasRequired(t => t.Model).WithMany();

しかし、私は完全に迷っているようです。この簡単な例で誰か助けてくれませんか?

4

1 に答える 1

16

あなたのコメントは重要な情報を明らかにします。その AModel をコンボボックスから BModel に追加すると、それまでに DbContext から切り離されます。それをモデルに追加すると、Entity Framework は新しいオブジェクトがあると見なします。

ID を DatabaseGenerationOptions.None として構成しているため、自分で指定した主キーが使用されます。あなたの場合、これは切り離されたオブジェクトの PK です。したがって、EF がこのエントリを挿入しようとすると、そのキーを持つエンティティが既に存在するため、上記の例外がスローされます。

これを解決するには、いくつかの方法があります。

  • 既存のエンティティを取得する

このエンティティは取得時にコンテキストにアタッチされ、これを使用できるようになります。ただし、これは追加のルックアップを意味します。最初にそれらをコンボボックスに取得し、次にコンボボックス内のエンティティの Id を使用してデータベースから再度取得します。

使用例:

AModel Get(AModel detachedModel)
{
    using(var context = new MyContext())
    {
        return context.AModels.Single(x => x.ID == detachedModel.ID);
    }
}
  • 既存のモデルをアタッチ

これにより、エンティティがデータベースに既に存在することを Entity-Framework が認識できるようになります。

using(var context = new MyContext())
{
    context.AModels.Attach(detachedModel);
}

アタッチする他の方法は、状態を Unchanged に設定することです

context.Entry(detachedModel).State = EntityState.Unchanged;

または Modified (値も変更した場合)

context.Entry(detachedModel).State = EntityState.Modified;
于 2015-04-18T19:39:37.163 に答える