0

これに関するすべての記事とスタックオーバーフローの質問を読んだと思いますが、解決策を見つけることができません。私のモデルから始めましょう

public class Entry
{
    public Entry ()
    {
        DateEntered = DateTime.Now;
    }

    public int Id { get; set; }
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    [Required]
    public string Email { get; set; }
    public string Number { get; set; }
    public string FbId { get; set; }
    [ReadOnly(true)]
    public DateTime DateEntered { get; set; }
    public string AccessToken { get; set; }

    //Relationsips
    public Backgrounds Background { get; set; }
    public Cars Car { get; set; }
}

public class Backgrounds
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Filename { get; set; }
}

public class Cars
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string FileName { get; set; }
}

コントローラで、エントリを更新しています。次のように

    // PUT /api/entries/5
    public HttpResponseMessage Put(Entry entry)
    {
        if(ModelState.IsValid)
        {

            _db.Entries.Attach(entry);
            _db.Entry(entry).State = EntityState.Modified;
            _db.SaveChanges();

            return new HttpResponseMessage(HttpStatusCode.NoContent);
        }

        throw new HttpResponseException(HttpStatusCode.BadRequest);
    }

私の Entry モデルは正しく更新されますが、たとえば entry.Background.Name が変更された場合、これはデータベースに保持されません。私のコントローラーは、その関係を含むエントリ モデル全体を受け入れます => 背景と車。ただし、リレーションシップに変更された値は更新も反映もされません。データベースにクエリを実行してから更新する必要のないエレガントなソリューションはありますか? 更新する前に余分なクエリやルックアップをしたくありません。

ありがとう

タイロン

4

1 に答える 1

0

オブジェクト グラフに対して行われたすべての変更について、手動で EF に通知する必要があります。エントリ インスタンスへの変更についてのみ EF に伝えましたが、関連するエンティティまたは関係自体への変更については伝えていません。これを解決するエレガントな方法はありません。通常、次の 2 つのオプションがあります。

  • エンティティの代わりにいくつかの DTO を使用し、これらの DTO には次のようなフラグがありIsDirtyます。オブジェクト グラフをコントローラーに戻すと、DTO からエンティティを再構築し、に基づいて状態を設定しIsDirtyます。たとえば、クライアントがリレーションも削除できる場合、このソリューションにはさらに拡張が必要です。
  • データベースからオブジェクト グラフをクエリし、受信した変更をデータベースから取得したエンティティにマージします。

関連するすべてのオブジェクトの状態を変更済みに設定して変更を強制的に保存し、新しいオブジェクトを識別するなどの部分的な解決策がありますが、Id == 0これらの解決策は特定のシナリオでのみ機能します。

この問題に関するより複雑な議論。

于 2012-05-16T09:08:40.463 に答える