2009-05-22 22 views
2

このコードは、実際に変更を保存するために失敗します。Entity Frameworkを持つ、厳密に型指定されたASP.NET MVC

// 
// POST: /SomeType/Edit/5 

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(Guid id, SomeType Model) 
{ 
    db.AttachTo(Model.GetType().Name, Model); 
    db.ApplyPropertyChanges(Model.EntityKey.EntitySetName, Model); 
    db.SaveChanges(); 
    return RedirectToAction("Index"); 
} 

ASP.NET MVCは、独立のEntityState値を持つ部署タイプEntityObjectように、オブジェクトモデルを作成し、

AttachToメソッドを使用した後、EntityStateは変更なしになります。

MSDN on Attaching Objects (Entity Framework)

オブジェクトは変更なし状態でオブジェクト コンテキストに取り付けられています。理由は、その変わらず状態の

、方法ApplyPropertyChangesは何もしません。

代わりに状態を変更したいです。です。
を独立

MSDN on EntityState Enumeration

オブジェクトが存在するが、それは、オブジェクト サービスによって追跡されていません。エンティティは の状態で、 を作成した直後、オブジェクト のコンテキストに追加する前にこの状態になります。エンティティは、デタッチ メソッドを呼び出すことによってコンテキストが から削除された後、または NoTrackingMergeOptionを使用してロードされた後、この 状態にもなります。それは コンテキストに又はSaveChangesメソッドを と呼ばれていたことを前回 ためロードされたので

不変オブジェクトは変更されていません。

修飾
オブジェクトが変更されるが、SaveChangesメソッドを が呼び出されていません。

明示的にEntityObjectのEntityStateプロパティをModifiedに設定することはできません。読み取り専用です。

厳密に型指定されたMVCコントローラをEntityObjectsで使用することは不可能ですか?

+0

http://stackoverflow.com/questions/922402/strongly-typed-asp-net-mvc-with-ado-net-entity-framework –

答えて

8

ObjectContextからObjectStateManagerを取得する必要があります。 ObjectStateManagerでは、明示的にデータベースへの呼び出しを行うために必要とせずに、あなたのオブジェクトの状態を設定することができます。

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(Guid id, SomeType Model) 
{ 
    db.AttachTo(Model.GetType().Name, Model); 

    ObjectStateManager stateMgr = db.ObjectStateManager; 
    ObjectStateEntry stateEntry = stateMgr.GetObjectStateEntry(model); 
    stateEntry.SetModified(); // Make sure the entity is marked as modified 
    //db.ApplyPropertyChanges(Model.EntityKey.EntitySetName, Model); 

    db.SaveChanges(); 
    return RedirectToAction("Index"); 
} 

ObjectStateEntryはまた、あなたがSetModifiedProperty経由でより細かい状態変化データを適用することができます。 SetModifiedを呼び出すと、EFはエンティティ全体を変更済みとして扱い、すべてのプロパティをデータストアに保持します。 SetModifiedPropertyを使用すると、EFはクエリを最適化し、実際に変更されたプロパティのみを関連付けることができます。 SetModifiedPropertyの使用は明らかに複雑です。通常、各プロパティの元の値を知る必要があるためです。

こちらがお役に立てば幸いです。 ObjectStateManagerは、EFツールボックス内の強力な小さなツールであり、EF v1.0の性能や効率を向上させるのに役立ちます。

+0

SetModifiedPropertyは期待通りに動作します。しかし、SetModifiedはエンティティ全体を変更されたものとして扱っていないようです。 「すべてのプロパティをデータストアに保持」するのではなく、何も保持しません。 –

+0

それはちょっと変わっています。何か他のことがあるかもしれません...しかし、どこかのバグのように聞こえます。 – jrista

+1

ObjectContextに関する素晴らしい答えと私のための新しい土地なので、知識に感謝します。私は最近、OCをDbContextに一時的にモーフィングして解決した同様の問題を抱えていました:http://stackoverflow.com/questions/33714849/objectcontext-with-entity-framework-6-inserting-duplicates-on-existing-related- e –

1

これは動作します:

// 
// POST: /SomeType/Edit/5 

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(Guid id, SomeType Model) 
{ 
    Model.EntityKey = (from SomeType s in db.SomeType 
         where s.Id == id 
         select s).FirstOrDefault().EntityKey; 
    db.ApplyPropertyChanges(Model.EntityKey.EntitySetName, Model); 
    db.SaveChanges(); 
    return RedirectToAction("Index"); 
} 

をしかし、データベースを照会せずに方法はありますか?

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(Guid id, SomeType Model) 
{ 
    db.AttachTo(Model.GetType().Name, Model); 
    Model.SomeProperty = Model.SomeProperty; // This looks hacky... =(
    db.ApplyPropertyChanges(Model.EntityKey.EntitySetName, Model); 
    db.SaveChanges(); 
    return RedirectToAction("Index"); 
} 

は、状態変化を行います。あなたは1行を追加するとどうなります

1

+0

私はModel.Id =モデルを試してみました。その特定のフィールドはEntity Frameworkによって保護されているため、例外が発生しました。私は他を試していませんでした。 –

+0

ええ、IDは読み取り専用です。他のいずれかを試してください... =) –

3

上記のどれも私にとってはうまくいかないようですが、MSDNのガイドの例では、元のアイテムをコンテキストから取得してから、更新されたアイテムを追加します。

第二の例:

http://msdn.microsoft.com/en-us/library/bb896248.aspx#Mtps_DropDownFilterText

private static void ApplyItemUpdates(SalesOrderDetail updatedItem){ 
// Define an ObjectStateEntry and EntityKey for the current object. 
EntityKey key; 
object originalItem; 

using (AdventureWorksEntities advWorksContext = 
    new AdventureWorksEntities()) 
{ 
    try 
    { 
     // Create the detached object's entity key. 
     key = advWorksContext.CreateEntityKey("SalesOrderDetail", updatedItem); 

     // Get the original item based on the entity key from the context 
     // or from the database. 
     if (advWorksContext.TryGetObjectByKey(key, out originalItem)) 
     { 
      // Call the ApplyPropertyChanges method to apply changes 
      // from the updated item to the original version. 
      advWorksContext.ApplyPropertyChanges(
       key.EntitySetName, updatedItem); 
     } 

     advWorksContext.SaveChanges(); 
    } 
    catch (InvalidOperationException ex) 
    { 
     Console.WriteLine(ex.ToString()); 
    } 
} 

}私が取得することができ、この作業ではなく、どのようなIAMを持って

1

は、私はそれを取得できますかSalesOrderDetail の親エンティティであります?

SalesOrderDetail.SalesOrderHeadがnullで、entityreferenceがnullです。 私の編集ルーチンは、SalesOrderDetailのIDにのみアクセスできます。

おかげ スリ

+0

新しい質問を開始するには、[Ask Question]リンクをクリックしてください。あなたの問題はもっと注目を集めるでしょう。 –

関連する問題