私は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に保存しようとすると、次のエラーが発生します。
PRIMARYKEY制約「PK_dbo.AModels」への違反。オブジェクト 'dbo.AModels'に重複するキーを挿入できません。重複するキー値は(48ee1711-8da4-46c1-a714-19e985211fed)です。\ r\nステートメントは終了しました。
これで解決すると思いました
modelBuilder.Entity<BModel>().HasRequired(t => t.Model).WithMany();
しかし、私は完全に迷子になっているようです。誰かがこの簡単な例で私を助けてくれますか?
あなたのコメントは重要な情報を明らかにします。そのAModelをコンボボックスからBModelに追加すると、それまでにDbContextから切り離されます。次にそれをモデルに追加すると、EntityFrameworkは新しいオブジェクトがあると見なします。
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);
}
アタッチする他の方法は、状態を未変更に設定することです。
context.Entry(detachedModel).State = EntityState.Unchanged;
または変更済み(値も変更した場合)
context.Entry(detachedModel).State = EntityState.Modified;