[解決済み】1つ以上の外部キーのプロパティが非NULLであるため、リレーションシップを変更できませんでした。
質問
あるエンティティでGetById()を行い、子エンティティのコレクションをMVCビューから来る私の新しいリストに設定すると、このエラーが発生します。
操作に失敗しました。その リレーションシップを変更できませんでした。 というのは、1つ以上の外部キー プロパティが NULL 値でない。このような場合 リレーションシップに変更が加えられると 関連する foreign-key プロパティが設定されます。 はヌル値である。foreign-keyがNull値でない場合 はNULL値をサポートしないので、新しい リレーションシップを定義し プロパティに割り当てる必要があります。 別の非NULL値、または を削除しなければならない。
この行がよくわからないのですが。
リレーションシップを変更できませんでした というのは、1つ以上の foreign-key プロパティが NULL 以外である。
なぜ2つのエンティティの関係を変更しなければならないのですか?アプリケーション全体のライフタイムを通じて同じであるべきです。
例外が発生したコードは、コレクション内の変更された子クラスを既存の親クラスに割り当てるという単純なものです。 これにより、子クラスの削除、新しいクラスの追加、および修正に対応できることを期待しています。 私はEntity Frameworkがこれを処理すると思っていました。
コードの行は、次のように集約されます。
var thisParent = _repo.GetById(1);
thisParent.ChildItems = modifiedParent.ChildItems();
_repo.Save();
解決方法は?
古い子項目を削除する必要があります
thisParent.ChildItems
を1つずつ手作業で行っています。Entity Frameworkはそれをやってくれません。古い子項目をどうしたいのか、捨てたいのか、それとも残して他の親エンティティに割り当てたいのか、最終的に決めることはできません。Entity Framework にあなたの決定を伝える必要があります。しかし、これらの2つの決定のうちの1つは、子エンティティがデータベース内のどの親にも参照されずに単独で生きることができないので、行わなければなりません(外部キー制約のため)。それは基本的に例外が言うことです。
編集
子項目の追加、更新、削除ができたらどうするか。
public void UpdateEntity(ParentItem parent)
{
// Load original parent including the child item collection
var originalParent = _dbContext.ParentItems
.Where(p => p.ID == parent.ID)
.Include(p => p.ChildItems)
.SingleOrDefault();
// We assume that the parent is still in the DB and don't check for null
// Update scalar properties of parent,
// can be omitted if we don't expect changes of the scalar properties
var parentEntry = _dbContext.Entry(originalParent);
parentEntry.CurrentValues.SetValues(parent);
foreach (var childItem in parent.ChildItems)
{
var originalChildItem = originalParent.ChildItems
.Where(c => c.ID == childItem.ID && c.ID != 0)
.SingleOrDefault();
// Is original child item with same ID in DB?
if (originalChildItem != null)
{
// Yes -> Update scalar properties of child item
var childEntry = _dbContext.Entry(originalChildItem);
childEntry.CurrentValues.SetValues(childItem);
}
else
{
// No -> It's a new child item -> Insert
childItem.ID = 0;
originalParent.ChildItems.Add(childItem);
}
}
// Don't consider the child items we have just added above.
// (We need to make a copy of the list by using .ToList() because
// _dbContext.ChildItems.Remove in this loop does not only delete
// from the context but also from the child collection. Without making
// the copy we would modify the collection we are just interating
// through - which is forbidden and would lead to an exception.)
foreach (var originalChildItem in
originalParent.ChildItems.Where(c => c.ID != 0).ToList())
{
// Are there child items in the DB which are NOT in the
// new child item collection anymore?
if (!parent.ChildItems.Any(c => c.ID == originalChildItem.ID))
// Yes -> It's a deleted child item -> Delete
_dbContext.ChildItems.Remove(originalChildItem);
}
_dbContext.SaveChanges();
}
注:これはテストされていません。これは、子項目コレクションの型が
ICollection
. (私は通常
IList
とすると、コードの見た目が少し変わってきます)。また、シンプルにするために、リポジトリの抽象的なものをすべて取り除きました。
それが良い解決策かどうかは分かりませんが、ナビゲーションコレクションのあらゆる変更に対応するためには、この路線で何らかの苦労をしなければならないと考えています。また、より簡単な方法があれば嬉しいですね。
関連
-
[解決済み] Entity Frameworkで生成されたSQLを表示するにはどうすればよいですか?
-
[解決済み】Entity Framework。1つのデータベース、複数のDbContexts。これは悪い考えなのか?[クローズド]。
-
[解決済み] EF 5 Code First Migrationsから完全なSQLスクリプトを生成する
-
[解決済み] Symfony2で現在のユーザを表すエンティティを取得する方法は?
-
[解決済み] Entity Framework 4 / POCO - 何から始めるか?[クローズド]
-
[解決済み] Entity Frameworkのバージョンは?
-
[解決済み] Entity FrameworkとSQL Server View
-
[解決済み] 特定のVSプロジェクトでのみパッケージマネージャーコンソールのマイグレーションを有効にするCommandNotFoundExceptionを発生させる
-
[解決済み] Entity Framework Code First - Fluent ApiとData Annotationsのメリット・デメリット【終了しました
-
[解決済み] Entity Framework コード 一意の列
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】識別関係と非識別関係の違いとは?
-
[解決済み】Entity Frameworkで複数のカラムにユニークキー制約を設定する
-
[解決済み] Entity Framework - やり直し - すべての移行を元に戻す/ロールバックする
-
[解決済み] キーワードはサポートされていません。"データソース" Entity Framework Contextの初期化
-
[解決済み] Entity Frameworkのバージョンは?
-
[解決済み] Entity Framework .Remove() と .DeleteObject() の比較
-
[解決済み] Entity Framework Code First - Fluent ApiとData Annotationsのメリット・デメリット【終了しました
-
[解決済み] Entity Framework コード 一意の列
-
[解決済み] エンティティフレームワークのコードファーストのNULL外部キー
-
[解決済み] EF Core の EntityTypeBuilder に ToTable の定義が含まれていない。