以下は、私が得ているエラーのサンプルです。コード名などは読みやすくするために変更されており、私が問題を抱えている部分だけを示すために「馬鹿げた」ものになっています。
テーブル構造:
まとめ
Entity Framework 3.5 を使用して ADDRESS と共に新しい CHILD アイテムを追加しようとしていますが、プロセスで 2 つのエンティティ キー参照を使用すると重複エントリ エラーが発生します。
コードの取り組み
最初に、エンティティの作成中に親参照を使用しようとしました:
public bool AddChild(Guid parentId, string firstName, string lastName, string address, string city, int provinceCode)
{
bool success = false;
using (Entities e = new Entities("connection string")
{
// prep address record
ADDRESS a = new ADDRESS
{
City = city,
Address = address,
PROVINCEReference = new System.Data.Objects.DataClasses.EntityReference<PROVINCE> { EntityKey = new System.Data.EntityKey("Entities.PROVINCEs", "ID", provinceCode) },
};
// prep owner record
CHILD c = new CHILD
{
PARENTReference = new System.Data.Objects.DataClasses.EntityReference<PARENT> { EntityKey = new EntityKey("Entities.PARENTs", "ID", new Guid(parentId)) },
ADDRESS = a,
FirstName = firstName,
LastName = lastName,
};
using (System.Transactions.TransactionScope transaction = new System.Transactions.TransactionScope())
{
try
{
e.AddToCHILDs(c);
e.AddToADDRESSes(a);
// Save changes pessimistically. This means that changes must be accepted manually once the transaction succeeds.
e.SaveChanges(false);
}
catch { }
}
}
return success;
}
両方の外部キーを参照しようとすると、これは機能しません。ただし、どちらか一方を参照しようとすると、正常に機能します。最初のものは常に機能します。2番目のものはエラーになります。それらがどのような順序であっても問題ありません。それらを単独で使用するか、このように他の方法で使用すると、正常に機能します。
また、次のような参照だけでなく、実際のアイテムを取得しようとしました。
PARENT o = e.PARENTs.First(x => x.ID.Equals(id));
PROVINCE p = e.PROVINCEs.First(x => x.ID.Equals(1));
a.PROVINCE = p;
c.ADDRESS = a
c.PARENT = o;
そして、同様のエラーを見つけた後、.Attach() メソッドで遊んでみました。
e.Attach(p);
e.Attach(o);
最初の方法(私の好みの方法)で行うと、最初に追加されたアイテムは問題なく動作します。2 番目のものを試すと、エラーが発生します (同じキーを持つアイテムが既に追加されています)。参照を使用するだけでなく、実際のレコードを取得してそれを実行しようとすると、SQL Server 2005 データベースから直接同じ種類のエラーが発生します。
これについて読んだ後、コンテキストとコードが親レコードの2つの異なるバージョンを参照している可能性があるという事実に関係していることは理にかなっています。しかし、私はそれを回避する良い方法を見つけることができません。
最後にやりたいことは、新しいアドレスを持つ子レコードを挿入することだけです。子レコードは親レコードを参照し、住所レコードは州レコードを参照する必要があります。できれば、参照を介してこれを実行し、SQL トランザクションを削減したいと考えています。
ありがとう!
編集
2 つの個別の entityKey オブジェクトと 2 つの個別の EntityReference<> オブジェクトを作成しようとしましたが、2 番目の EntityReference<> オブジェクトを使用して関係/参照を割り当てようとすると、次のエラーが発生します。
エンティティー参照が属するオブジェクトの関係マネージャーが既に ObjectContext にアタッチされているため、EntityReference を初期化できませんでした。
編集
Alex の回答からの関係/参照情報を必要としない回避策の使用: Entity Framework EntityKey / Foreign Key problem
コンテキストに既に含まれている情報を確認するためにチェックを行う必要があり、回避策としてそれを通過するために「偽の」レコードを作成するため、これを使用しないことをお勧めします。誰かがもっと情報を持っているなら、私は聞きたいです!