实体框架与相关实体更新(Entity Framework Updating with Related

2019-08-31 15:28发布

我使用的是EF尝试更新ASP.NET的实体。 我创建的实体,将其设置的属性然后用ID传递回EF在一个单独的层,从而可以应用的变化。 我这样做,因为我只存储实体的ID,当它被绑定到UI控件。

一切工作的标准属性,但我不能更新产品的Category.ID(相关实体)。 我试过的EntityKey,的EntityReference和其他几个,但类别ID不会被保存。 这是我有:

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();
 }
}

我真的想用EF,但我似乎有与使用它与ASP.NET的几个问题。

Answer 1:

这是接受了这个问题的答案的强类型ASP.NET MVC实体框架

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

你试过了吗?

[更新,在上面的代码不起作用]

这是小的扩展属性我用这样一个代码块是比较容易理解:

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;
        }
    }
}

并为我工作(此时肯定):

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();

为了确保它看起来哈克。 我认为原因是因为EF关系具有地位的实体(修改,增加,删除),并基于该状态EF改变外键的值或删除行如果多对多的关系是如此。 出于某种原因(不知道为什么)的关系状态没有改变一样的财产状况。 这就是为什么我必须设置originalItem的CategoryReference.EntityKey为了改变这种关系的状态。



Answer 2:

失败的原因是双重的。

  1. 为了更新引用(即Product.Category),你必须在上下文中的原始参考值了。
  2. ApplyPropertyChanges(...)只适用于实体的常规/标量属性,基准保持不变

所以我会做这样的事情(注意:此代码使用了大量的一招叫存根实体 ,以避免与周围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();
 }
}

这将做的工作,假设没有错别字等。



文章来源: Entity Framework Updating with Related Entity