Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用集合将实体框架更新为对象的方法_C#_.net_Entity Framework_Ef Code First_Code First - Fatal编程技术网

C# 使用集合将实体框架更新为对象的方法

C# 使用集合将实体框架更新为对象的方法,c#,.net,entity-framework,ef-code-first,code-first,C#,.net,Entity Framework,Ef Code First,Code First,我在更新数据库中的现有实体时遇到问题。我首先使用实体框架代码 我有一个计算食物的小程序 我的域类> public class Unit { public int Id { get; set; } public string Name { get; set; } } public abstract class Item { public int Id { get; set; } public string N

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

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

我的域类>

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; }
    }
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无法跟踪具有相同密钥的多个对象

我在更新表格>单位和成分方面没有问题,但收集让我感到紧张。我已经在pluralsight上观看了有关EF的视频,但没有像我这样的例子

谢谢你的帮助。

试试这个

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

您误用了构建实体框架的目的。通常,最好加载一个实体,修改它(让附加的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。只有当属性不是集合时,这才有效,否则我需要像Ryan Amies写的那样这样做。
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();
}