Frage

Ich bin der EF zu versuchen, eine Einheit mit ASP.NET zu aktualisieren. Ich bin eine Einheit zu schaffen, es ist das Festlegen von Eigenschaften es dann vorbei mit der ID auf einer separaten Ebene mit dem EF zurück, so dass die Änderung angewendet werden kann. Ich bin dies zu tun, weil ich nur die ID des Unternehmens speichern, wenn es um den UI-Steuerelemente gebunden worden ist.

Alles funktioniert für Standardeigenschaften, aber ich kann die Category.ID eines Produkts (a verbundene Einrichtung) nicht aktualisieren. Ich habe versucht, EntityKey, EntityReference und ein paar andere, aber die Kategorie-ID wird nicht gespeichert. Das ist, was ich habe:

Product product = new Product();
product.CategoryReference.EntityKey = new EntityKey("ShopEntities.Categories", "CategoryID", categoryId);
product.Name = txtName.Text.Trim();
... other properties
StockControlDAL.EditProduct(productId, product);

public static void EditProduct(int productId, Product product) {
 using(var context = new ShopEntities()) {
     var key = new EntityKey("ShopEntities.Products", "ProductID", productId);
     context.Attach(new Product() { ProductID = productId, EntityKey = key });
     context.AcceptAllChanges();
     product.EntityKey = key;
     product.ProductID = productId;
     context.ApplyPropertyChanges("ShopEntities.Products", product);
     context.SaveChanges();
 }
}

Ich mag wirklich die EF verwenden, aber ich scheine ein paar Probleme mit der Verwendung mit ASP.NET sein zu müssen.

War es hilfreich?

Lösung

Dies wird akzeptierte Antwort auf diese Frage stark typisierte ASP.NET MVC mit Entity Framework

context.AttachTo(product.GetType().Name, product);
ObjectStateManager stateMgr = context.ObjectStateManager;
ObjectStateEntry stateEntry = stateMgr.GetObjectStateEntry(model);
stateEntry.SetModified();
context.SaveChanges();

Haben Sie das ausprobiert?

[Aktualisiert Code oben funktioniert nicht]

Dies ist kleine Erweiterungseigenschaft ich so nächsten Codeblock verwendet wird, ist leichter zu verstehen:

public partial class Product
{
    public int? CategoryID
    {
        set
        {  
           CategoryReference.EntityKey = new EntityKey("ShopEntities.Categories", "CategoryID", value);
        }
        get
        {
            if (CategoryReference.EntityKey == null)
                return null;

            if (CategoryReference.EntityKey.EntityKeyValues.Count() > 0)
                return (int)CategoryReference.EntityKey.EntityKeyValues[0].Value;
            else
                return null;
        }
    }
}

und das funktionierte für mich (diesmal sicher):

System.Data.EntityKey key = new System.Data.EntityKey("ShopEntities.Products", "ProductID", productId);
        object originalItem;   

        product.EntityKey = key;
        if (context.TryGetObjectByKey(key, out originalItem))
        {
            if (originalItem is EntityObject &&
                ((EntityObject)originalItem).EntityState != System.Data.EntityState.Added)
            {
                Product origProduct = originalItem as Product;   
                origProduct.CategoryID == product.CategoryID;//set foreign key again to change the relationship status           
                context.ApplyPropertyChanges(
                    key.EntitySetName, product);

            }
        }context.SaveChanges();

Für sicher, dass es aussieht Hacky. Ich denke, dass der Grund ist, weil die EF Beziehungen Status als Entitäten (geändert, hinzugefügt, gelöscht) und auf der Grundlage dieser Status EF den Wert der Fremdschlüssel ändert oder löscht Zeile, wenn viele zu viele Beziehung in Fall ist. Aus irgendeinem Grund (weiß nicht warum) die Beziehungsstatus ist nicht das gleiche wie Eigentumsstatus geändert. Deshalb hatte ich die CategoryReference.EntityKey auf originalItem setzen, um den Status der Beziehung zu ändern.

Andere Tipps

Der Grund, dies nicht gelingt ist zweifach.

  1. Um eine Referenz zu aktualisieren (das heißt Product.Category) Sie den ursprünglichen Referenzwert im Kontext haben müssen.
  2. ApplyPropertyChanges (...) gilt nur für regelmäßige / Skalar Eigenschaften des Entity wird die Referenz unverändert gelassen

Also ich würde so etwas tun (Beachten Sie diesen Code macht intensiven Gebrauch von einem Trick namens Stub-Einheiten zu vermeiden herumschlagen mit EntityKeys)

Product product = new Product();
// Use a stub because it is much easier.
product.Category = new Category {CategoryID = selectedCategoryID};
product.Name = txtName.Text.Trim();
... other properties

StockControlDAL.EditProduct(productId, originalCategoryID);


public static void EditProduct(Product product, int originalCategoryID ) {
 using(var context = new ShopEntities()) 
 {
     // Attach a stub entity (and stub related entity)
     var databaseProduct = new Product { 
             ProductID = product.ProductID, 
             Category = new Category {CategoryID = originalCategoryID}
         };
     context.AttachTo("Products", databaseProduct);

     // Okay everything is now in the original state
     // NOTE: No need to call AcceptAllChanges() etc, because 
     // Attach puts things into ObjectContext in the unchanged state

     // Copy the scalar properties across from updated product 
     // into databaseProduct in the ObjectContext
     context.ApplyPropertyChanges("ShopEntities.Products", product);

     // Need to attach the updated Category and modify the 
     // databaseProduct.Category but only if the Category has changed. 
     // Again using a stub.
     if (databaseProduct.Category.CategoryID != product.Category.CategoryID)
     {
         var newlySelectedCategory = 
                 new Category {
                     CategoryID = product.Category.CategoryID
                 };

         context.AttachTo("Categories", newlySelectedCategory)

         databaseProduct.Category = newlySelectedCategory;

     }

     context.SaveChanges();
 }
}

Dies wird die Arbeit erledigen, sofern keine Tippfehler etc.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top