【问题标题】:Entity Framework Update method to object with collection实体框架更新方法与集合对象
【发布时间】:2013-08-16 13:24:32
【问题描述】:

我在更新数据库中的现有实体时遇到问题。我首先使用实体​​框架代码。

我有计算食物的小程序。

我的域类>

public class Unit
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

public abstract class Item
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

public class Ingredient : Item
    {        
        public virtual Unit Unit { get; set; }               
        public decimal Price { get; set; }        
    }

public class Recipe : Item 
    {
        public virtual List<RecipeItem> Items { get; set; }
        public double WeightCoocked { get; set; }
        public bool IsAlsoIngredient { get; set; }        
    }

public class RecipeItem
    {
        public int Id { get; set; }
        public virtual Item Item { get; set; }        
        public int Quantity { get; set; }
    }

请注意,RecipeItem 可以是成分,也可以是食谱,所以我可以将食谱包含在食谱中。

我试过这种更新方法:

public void Update1(Recipe recipe)
        {            
            if (recipe == null) 
                return;                

            var originalRecipe = DataContext.Recipes.FirstOrDefault(i => i.Id == recipe.Id);

            if (originalRecipe == null) 
                return; 

            DataContext.Entry(originalRecipe).CurrentValues.SetValues(recipe);

            DataContext.SaveChanges();
        }

Update1 有效,但我的收藏没有更新。

public void Update2(Recipe recipe)
        {            
            if (recipe == null) 
                return;                

            var originalRecipe = DataContext.Recipes.FirstOrDefault(i => i.Id == recipe.Id);

            if (originalRecipe == null) 
                return; 

            DataContext.Entry(originalRecipe).State = EntityState.Modified;

            DataContext.SaveChanges();
        }

Update1 的工作方式与 Update1 相同,但如果我更改集合,则会出现异常。 我也试过把这条线放在那里

DataContext.Entry(originalRecipe.Items).State = EntityState.Modified;

上次更新方法>

public void Update3(Recipe recipe)
        {            
            if (recipe == null) 
                return;                

            var originalRecipe = DataContext.Recipes.FirstOrDefault(i => i.Id == recipe.Id);

            if (originalRecipe == null) 
                return; 

            DataContext.Recipes.Attach(recipe);
            DataContext.Entry(originalRecipe).State = EntityState.Modified;
            DataContext.Entry(originalRecipe.Items).State = EntityState.Modified;

            DataContext.SaveChanges();
        }

得到相同的异常: ObjectStateManager 中已存在具有相同键的对象。 ObjectStateManager 无法跟踪具有相同键的多个对象。

我没有更新表格的问题> 单位和成分,但收集让我紧张。我已经在复数视觉上看过关于 EF 的视频,但没有像我这样的例子。

感谢您的帮助。

【问题讨论】:

    标签: c# .net entity-framework ef-code-first code-first


    【解决方案1】:

    您误用了 Entity Framework 的用途。通常,加载一个实体,修改它(让附加的 DbContext 为您跟踪更改),然后允许它检测是否已进行更改是一个好主意。如果这是不可能的(我会假设你已经问过这个问题),那么你最好的选择是将实体的属性从一个对象映射到另一个对象。您也需要对相关实体中的每个实体执行此操作。

    public void Update(Recipe recipe)
    {            
        if (recipe == null) 
            return;                
    
        var originalRecipe = DataContext.Recipes.SingleOrDefault(i => i.Id == recipe.Id);
    
        if (originalRecipe == null) 
            return; 
    
        originalRecipe.Name= recipe.Name;
        originalRecipe.WeightCooked = recipe.WeightCooked;
        originalRecipe.IsAlsoIngredient = recipe.IsAlsoIngredient;
    
        foreach(var item in recipe.Items)
        {
            var originalItem = DataContext.RecipeItems.SingleOrDefault(i=>i.Id == item.Id);
            if(originalItem == null)
                return;
            originalItem.Quantity = item.Quantity;
            ...
        }
        DataContext.SaveChanges();
    }
    

    顺便说一句,我使用了SingleOrDefault 而不是FirstOrDefault

    如果您想自动执行此映射,请查看AutoMapper 之类的内容,它允许您将对象映射在一起。

    【讨论】:

    • 谢谢。我只是在想是否有任何选项如何自动映射所有更改。
    • 如果您想自动映射属性,请查看 automapper。
    【解决方案2】:

    试试这个

    public void Update1(Recipe recipe)
            {            
                if (recipe == null) 
                    return;                
    
                var originalRecipe = DataContext.Recipes.FirstOrDefault(i => i.Id == recipe.Id);
    
                if (originalRecipe == null) 
                    return; 
    
                originalRecipe.YOurPepertiNameToUpdate = recipe.YOurPepertiNameToUpdate ;
                originalRecipe.YOurPepertiNameToUpdate1 = recipe.YOurPepertiNameToUpdate1;
                originalRecipe.YOurPepertiNameToUpdate2 = recipe.YOurPepertiNameToUpdate2 ;
    
                DataContext.SaveChanges();
            }
    

    【讨论】:

    • 这只有在属性不是集合的情况下才有效,否则我需要像 Ryan Amies 写的那样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多