私はSOの検索を試みましたが、私が見つけたすべての結果は既にDBに保存されているエンティティのPKの更新に対応しています。私の場合は違う。複数のリンクされた1-1のリレーションがPKを期待通りに同期していません
私は1-0.1の関係を持つデータベースに3つのテーブルを持っています。関係は次のようになります。「< - 」
A <- B <- C
主要エンドに関係してポイントを表します。私。各Bには常に関連するAがありますが、AにはBがありません。つまり、Aの基数は1、Bの値は0..1です。
各関係は、子エンティティのPKから親エンティティのPKに向かうFKによって表されます。各PKは、クライアント生成値を持つuniqueidentifier
Id
列です。私は同じ基数を持つ同じ関係を持つデータベースからEF 4モデルを生成しました。
B
とC
という子エンティティを既存のA
エンティティに追加しようとしています。設計上の理由から、いくつかの新しいインスタンスが1つの平和なコードで作成され、A
エンティティは別のエンティティのB
エンティティにリンクされています。さらに、後者はC
が存在することを知りたくありません。
public B CreateB()
{
return new B
{
Id = Guid.NewGuid(),
C = new C(),
};
}
そして今リンクとコードを保存します:ここで
はB
とC
作成コードがどのように見えるかだ
// a is an instance of A that has been loaded from DB
// and hence has a persistent Id value.
// b is a just-created instance of B
// that has a non-persistent Id value and null reference to A.
void SaveBlahBlahBlah(A a, B b)
{
// At this point b and c have the same Id value.
// It differs from a's Id, but that's expected, they haven't been linked yet.
b.A = a;
// At this point b receives a's Id value, but c keeps the original one,
// therefore the existing b-c link gets broken!
using(var ctx = new MyContext())
{
ctx.As.Attach(a); // This throws exception saying
// I've violated referential integrity.
// It doesn't say which relationship is broken,
// but I guess it's the B-C one since
// the debugger shows them to have different values if PKs
ctx.Bs.AddObject(b);
ctx.SaveChanges();
}
}
私は(両方ともデフォルトEFのコードジェネレータでこれを試してみました生成されたエンティティの基本クラスとしてEFのEntity
クラスを使用するもの)およびセルフトラッキングエンティティコードジェネレータを使用します。結果は同じです。
コードがクラッシュします。その理由は、A
とB
がリンクされた後に、B
とC
が1-1の関係を持つエンティティで違法な違うPK値を取得する可能性があります。
私が期待していたのは、Cが自動的に値をB
A
から取得した値に同期しているということでした。オブジェクトグラフで作業しているので妥当だと思われます。既存のB
- C
の関係はOKですが、B
とA
をリンクしても問題ありません。なぜそれは壊れますか? DBにB
またはC
のいずれかが存在し、私がPKを変更できなかった場合、私はそれを理解するでしょう。しかし、それは事実ではない、両方のentitesはちょうど作成されています。
EFはPKであるために1-1の関係の両側を必要とするため、FKのPK列とは別のものを使用して鍵のチェーンを破ることはできません。
私はキーを手動で同期させたくありません。実際には、関連するテーブルが1つ以上あり、同期コードが多くの場所に表示される必要があります。
STEジェネレータのT4テンプレートを更新して、PKアップデートをカスケード接続して1-1の関係にすることができると信じています。しかし、私はあまりにもT4に精通していないとあまりにもそれを行うことは幸せではない。
私は2つの質問がある:
- 私の場合、カスケード接続PK更新の私の期待は、いくつかの理由で間違ってますか? (しかし、奇妙に見えます)私は、それはバグか機能ですか?
- STEテンプレートを変更する以外に、問題を解決する方法が他にもありますが、できれば簡単ですか? EFのマッピングや文脈での魔法のオプションがあるかもしれませんか?
ありがとうございます。
+1非常に明確な説明! –
ありがとうございます。私はAttachを使用したことに注意してください。EFがなければ、DBにAがすでに存在していたのでエラーにつながったAを挿入しようとしました。私はモデルとフレーバーを変更しました(私は当時からEFCFを使用していました)。だから、あなたの提案がうまくいくかもしれない、私はそれを試してみましょう。 –
あなたは 'Attach'を使うことができますが、Bとの関係を作る前にそれをする必要があります。 –