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