2011-01-10 14 views
0

私は数日間この上に私の髪を引き裂きました、そして、私が完全に脱毛する前に、これを行う方法を私よりも賢く全員に頼む時が来ました。Entity Framework Code Firstアプローチを使用してエンティティを編集するにはどうすればよいですか?

が、私は今、コードファーストCTP 5およびMVC 3

で例外メッセージをEntity Frameworkの4を使用していても同じキーを持つオブジェクトが既にObjectStateManagerに存在する」である。ObjectStateManagerが持つ複数のオブジェクトを追跡することはできません同じ鍵です。 "クライアントインターフェイス上の保存方法がこれです

public ActionResult Save(ClientEntity postedClient) 
    { 
     try 
     { 
      if (ModelState.IsValid) 
      { 
       Base.clientInterface.Save(postedClient); 
       return RedirectToAction("Index"); 
      } 
     } 
     catch (Exception) 
     { 

      throw; 
     } 

     SetupManageData(null, postedClient); 
     return View("Manage"); 

    } 

public void Save(ClientEntity theClient) 
    { 
     SetContext(); 


     if (theClient.clientId == 0) 
      this.pContext.Clients.Add(theClient); 
     else 
     { 
      ClientEntity existingClient = GetSingle(theClient.clientId); // Get the existing entity from the data store. 

      // PseudoCode: Merge existingClient and theClient - Can this be done without using ObjectStateManager?    
      // PseudoCode: Attach merged entity to context so that SaveChanges will update it in the database - is this correct? 
     } 

     this.pContext.SaveChanges(); 

    } 

    private void SetContext() 
    { 
     if (this.pContext == null) 
      this.pContext = new PersistanceContext();   
    } 

持続性コンテキストがDBContextであり、このようになります。ここで

まずアップは、編集フォームがに投稿されたコントローラであり、 :

public class PersistanceContext : DbContext 
{ 
    public DbSet<ClientEntity> Clients { get; set; } 
} 

答えて

0

clientInterfaceのライフスタイルは何ですか?シングルトンなのか、それとも複数のリクエストに生き続けるものなのでしょうか?

私の推測では、GETリクエストでエンティティを取得するために使用されたデータベースコンテキストのライブインスタンスが保持されていて、POSTがクライアントエンティティをコンテキストに追加しようとすると、彼らは矛盾します。

リクエストごとにclientInterfaceの後ろにあるオブジェクトを破棄してみてください。たぶんWebリクエストごとのライフスタイルをサポートするDIコンテナを使用して、心配する必要はありません。

私の推測は正しかったと思いますが、これは助けになります。

0

これは動作するはずです。

if (theClient.clientId == 0) 
    { 
     this.pContext.Clients.Add(theClient); 
    } 
    else 
    { 
     ClientEntity existingClient = this.pContext.Clients.Single(o => o.ClientId == theClient.ClientId); 

     // map properties 
     existingClient.Name = theClient.name; 
     // .... 

    } 

    this.pContext.SaveChanges(); 

[編集]

それは2つの別々のビューにオブジェクトの作成&編集を分割するために、私はTryUpdateModelを使用するプロパティのマッピングを避けるために(私見)方が簡単です。

[HttpPost] 
public ViewResult Edit(int clientID, FormCollection collection) 
{ 
    var client = pContext.Clients.SingleOrDefault(o => o.ID == clientID); 

    if(!TryUpdateModel(client, collection)) 
    { 
     ViewBag.UpdateError = "Update Failure"; 
    } 
    else 
    { 
     db.SubmitChanges(); 
    } 

    return View("Details", client); 
} 

[HttpPost] 
public ViewResult Create(FormCollection collection) 
{ 
    var client = new Client(); 

    if(!TryUpdateModel(client, collection)) 
    { 
     ViewBag.UpdateError = "Create Failure"; 
    } 
    else 
    { 
     db.Clients.Add(client); 
     db.SubmitChanges(); 
    } 

    return View("Details", client); 
} 
+0

私は実際にプロパティを手動でマップする必要がないようにしています。そうしないと、新しいプロパティが追加された場合に間違いの余地があります。 –

+0

はい、私は常にオブジェクトの作成と編集を2つのビューに分割し、TryUpdateModel()を使用してプロパティをマップします。 –

関連する問題