2011-01-12 19 views
7

私は2つのプロジェクトを持っています - EDM Entity Frameworkモデルと別個のASP.NET MVCプロジェクトを含むクラスライブラリ。ASP.NET MVC 3でEF 4エンティティを更新するには?

MVCを使用してエンティティの変更を編集して保存する方法に問題があります。私のコントローラでは、私が持っている:

public class UserController : Controller 
    { 
     public ActionResult Edit(int id) 
     { 
      var rep = new UserRepository(); 

      var user = rep.GetById(id); 

      return View(user); 
     } 

     [HttpPost] 
     public ActionResult Edit(User user) 
     { 
      var rep = new UserRepository(); 

      rep.Update(user); 

      return View(user); 
     } 
    } 

マイUserRepositoryは、このような更新方法があります。今

public void Update(User user) 
{ 
    using (var context = new PDS_FMPEntities()) 
    { 
     context.Users.Attach(testUser); 
     context.ObjectStateManager.ChangeObjectState(testUser, EntityState.Modified); 
     context.SaveChanges(); 
    } 
} 

、私は編集ユーザページ上で「保存」をクリックし、パラメータuserは2つのだけの値が含まれていますpopulated:Id、およびFirstName。私はそれを取っているのは、ビュー内の2つのプロパティのみを表示しているからです。

ユーザーのファーストネームを更新して保存したい場合は、ビューに表示されていない他のUserプロパティについて、私は何をすると思いますか? userオブジェクトのNULL値?

私はスタブエンティティの使用について多くのことを読んできましたが、実際には見たことのない例がないので、どこも高速になりません。つまり、EntityKeyに関連する例外が引き続き発生します。

誰かがMVCフロントエンドによって呼び出されたリポジトリクラスを使用してEF 4エンティティを更新する方法の良いチュートリアル/例を教えてくれますか?

答えて

1

OK、いくつかの試行錯誤の後、私は解決策を見つけたようだ。ここに私の更新Update方法がUserRepositoryである:

public void Update(User user) 
{ 
    using (this.Context) 
    { 
     var tempUser = new User { usr_id = user.usr_id }; 

     this.Context.Users.Attach(tempUser); 
     this.Context.ApplyCurrentValues("Users", user); 
     this.Context.SaveChanges(); 
    } 
} 

私が試した他の例のいくつかは、上記に非常に近かったが、ちょうどマークを逃しました。

+2

@Jasonエヴァンスを - スタブ技術と呼ばれ、そして唯一のスカラプロパティのために動作します。ビューにバインドしている 'User.Addresses'のようなナビゲーションプロパティがある場合、上記はアドレスを更新しません。 DBから再度Userを取得し、次に 'TryUpdateModel'を使用してオブジェクトを更新することをお勧めします。詳細については、私の最近の質問/回答を参照してください:http://stackoverflow.com/questions/4653834/asp-net-mvc-ef4-poco-repository-how-to-update-relationships/4666466#4666466 – RPM1984

+0

@ RPM1984 - それはナビゲーション特性の面倒を節約するでしょう。私がTryUpdateModel()を使用して懸念しているのは、デザインです。私は物事の取得/保存/削除に対処するためにリポジトリを使用できることを保証しようとしています。 TryUpdateModel()を使用することで、これをコード化する方法の良いデザインの提案がありますか?私が意味するものを見れば、コントローラがデータベース関連のコードを処理することは望ましくありません。 –

+0

いいえ、あなたが何を意味するのか分かりません。私は推測しますが、あなたのリポジトリに標準の "保存"メソッドを作成します。このメソッドは、新しい/既存のオブジェクト(IDなどに基づいています)の場合は「把握」します。したがって、repository.Updateまたはrepository.Addを呼び出す必要はありません。 TryUpdateModelをクリックして保存します。あなたがあなたのエンティティをあなたのエンティティに触れさせたくないというあなたの言及 - 私はあなたの懸念を理解していません。コントローラは、モデルをリフレッシュするためのものです。そして、それは "オブジェクト"を更新することです - あなたのリポジトリは上記のオブジェクトの永続性に依然として関心があります。 – RPM1984

2

私はデータベースからユーザーを取得し、そのエンティティを更新します。 EFは、どの値が修正されるべきか、どの値が修正されるべきかを魔法のように知ることはできません。

同時実行性の問題が懸念される場合は、タイムスタンプをビューに保存する必要があります。通常は、隠しフォームの値です。

0

私はasp.netのWebサイトで、このチュートリアルでは、非常に有用であることが判明:Getting Started with EF using MVC - Updating Related Data

に注意を払うために方法は(にエンティティを設定する「標準」のように、関連するモデルを更新しますどのTryUpdateModelです変更された状態とすべてを渡します)、次に、特定のプロパティーがどのように更新されるかをカスタマイズすることができます。

エンティティキーの問題が発生し、これが過去の問題を解決するのに役立ちました。

+1

入力いただきありがとうございます。私はこれをEFに関するリソースリストに残しておきます。とても有難い。 –

0

これはおそらく質問に答えるのに少し遅れているかもしれませんが、おそらくそれは他の人に役立つでしょう。主な問題は、ページがレンダリングされた後にエンティティを読み取るデータベースコンテキストインスタンスが破棄されるためです。だからあなたがそれを保存しようとすると、これはコンテキストの新しいインスタンスなので、以前のコンテキスト呼び出しを知りません。したがって、Entity Frameworkは、変更された行がわからないため、データベース内のすべての行を更新する必要があります。

これは、すべての古いデータを保存し、変更したいものを更新するために見つけた最良の方法は、まずデータベースに新しい呼び出しを行い、必要なすべての情報をモデル(またはデータを格納するために使用しているもの)をDBに現在あるものにモデル化します。その情報に必要な変更を加え、結果をDBに保存します。

ます。詳細についてはこちらを実装基本的なCRUDのチュートリアルを見ることができます。 http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application

関連する問題