ton*_*nco 3 .net c# entity-framework code-first ef-code-first
我在更新DB中的现有实体时遇到问题.我正在使用Entity Framework 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 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; }
}
Run Code Online (Sandbox Code Playgroud)
请注意,RecipeItem可以是Ingredient,也可以是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();
}
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
Update1的工作方式与Update1相同,但如果我更改了集合,我就会遇到异常.我也尝试过这一行
DataContext.Entry(originalRecipe.Items).State = EntityState.Modified;
Run Code Online (Sandbox Code Playgroud)
最后更新方法>
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();
}
Run Code Online (Sandbox Code Playgroud)
获得相同的异常:ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法使用相同的键跟踪多个对象.
我更新表>单位和成分没有问题,但收集让我感到紧张.我已经在复数视频上看过关于EF的视频,但是没有像我这样的例子.
谢谢您帮忙.
您误用了构建实体框架的内容.通常,加载实体,修改它(让附加的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();
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我用的是SingleOrDefault代替FirstOrDefault.
如果您想自动执行此映射,请查看AutoMapper之类的内容,它允许您将对象映射到一起.