将Entity Framework Update方法更新到具有集合的对象

本文关键字:集合 对象 更新 Entity Framework Update 方法 | 更新日期: 2023-09-27 18:27:54

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

我有一个计算食物的小程序。

我的域名类别>

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可以是Ingredient,也可以是Recipe,所以我可以将Recipe包含在Recipe中。

我尝试了这种更新方法:

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无法跟踪具有相同键的多个对象。

我对更新表格>单位和配料没有问题,但收集让我很紧张。我已经看了很多关于英孚的视频,但没有像我这样的例子。

谢谢你的帮助。

将Entity Framework Update方法更新到具有集合的对象

您正在滥用实体框架的构建目的。通常,最好加载一个实体,对其进行修改(让附加的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这样的东西,它可以让你把对象映射在一起。

试试这个

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