0

私はFileエンティティとエンティティを持っていUserます。エンティティは、というプロパティを通じてエンティティFileと 1:1 の関係を持ちます(これは、ファイルを最後に変更したユーザーを記録します)。という名前のエンティティ内にもフィールドがあり、これは実際の FK リレーションシップです。リレーションシップは一方向です。エンティティには、エンティティに戻るナビゲーション プロパティがありません。UserLastChangeUserFileLastChangeUserIdUserFile

class File
{
    public int Id { get; set; }

    public int? LastChangeUserId { get; set; }
    public virtual User LastChangeUser { get; set; }
}

class User
{
    public int Id { get; set; }
}

Fileが変更された場合、に を設定する必要がLastChangeUserありFileます。完全な User オブジェクトではなく、ユーザーの ID しか持っていません。だから、私はこれをやっています:

file.LastChangeUser = null;
file.LastChangeUserId = userId;

Fileこれは、オブジェクトが新しく作成されたときにファイルを作成する際に機能するようです (エンティティ コレクションに追加される POCO)。

Fileただし、オブジェクトが DB から (プロキシとして) 取得された既存のオブジェクトである場合、ファイルの更新時には機能しません。

後者の場合、LastChangeUserIdフィールドの DB で NULL になります。(SaveChanges の呼び出し後、オブジェクトはとフィールドnullの両方に含まれます)。LastChangeUserLastChangeUserId

多分私はここで間違ったことをしているだけですか?正しい方法は何ですか?プロパティUserを設定するためにオブジェクトを取得する必要がありますか?LastChangeUser

4

1 に答える 1

1

@kevin_fitz ソリューションがここで機能する理由は、EF の変更追跡と検証の方法によるものです。EF での変更追跡の既定の動作は、スナップショット追跡と呼ばれる方法であり、最初に読み込まれたときにすべてのエンティティの初期状態を基本的に複製します。EF で変更を保存すると、各エンティティの元のスナップショットが現在の状態のオブジェクト (変更しているオブジェクト) と比較され、相違点がデータベースに保持されます。

この EF に加えて、エンティティに対して送信前の検証も実行します (FYI を無効にすることができます)。

あなたの場合、保存時にスナップショットトラッカーによって検出されるモデルに2つの変更を加えました(実際には競合します)。ただし、トラッカーは、これが必要な関係であり、null に設定できないことを検出する検証ルールを通じて、これらの両方を処理しようとします。これが、このエラーが表示される理由であり、null 更新を削除すると問題が解決する理由です。

余談ですが、実際にはナビゲーション プロパティのオブジェクトまたはキーのいずれかを更新するだけで、そのデータベース リレーションシップの更新がトリガーされます。ナビゲーション プロパティが EF コードでどのように機能するかの詳細については、まず私の記事をチェックしてください: http://blog.staticvoid.co.nz/2012/07/entity-framework-navigation-property.html

于 2012-10-14T02:43:03.513 に答える