在使用EF更新数据的时候,报如下错:
ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。
原因是:在EF上上下文中不允许存在2个具有相同键的实体。如下(关注下划线的的代码就Ok了):
public static object BacthSave<T>(string insertedRows, string updatedRows, string deletedRows) where T : class
{
try
{
//添加
if (!string.IsNullOrEmpty(insertedRows))
{
List<T> insertedList = JsonHelper.DeserializeData<List<T>>(insertedRows);
foreach (var model in insertedList)
{
//db.Sys_Navigations.Add(btn);
db.Entry(model).State = EntityState.Added;
}
//db.Sys_Buttons.Add(unicorn);//添加到上下文中
//插入到数据库中
}
//修改
if (!string.IsNullOrEmpty(updatedRows))
{
Type type = typeof(T);
List<T> updatedList = JsonHelper.DeserializeData<List<T>>(updatedRows);
PropertyInfo propertyInfo = type.GetProperty("Id");
foreach (var model in updatedList)
{
//注意以下的提示内容,属性名,属性的类型
//string n = propertyInfo.Name;
//n = propertyInfo.PropertyType.Name;
//n = propertyInfo.PropertyType.FullName;
Nullable<int> id = propertyInfo.GetValue(model) as Nullable<int>;
//string id = model.GetType().InvokeMember("Id", System.Reflection.BindingFlags.GetProperty, null, model, null) as string;//这个方法没测试通过,不知道为啥,求留言
var entry = db.Entry(model);
if (entry.State == EntityState.Detached)
{
var set = db.Set<T>();
T attachedProduct = set.Local.SingleOrDefault(p => propertyInfo.GetValue(p) as int? == id);
//如果已经被上下文追踪
if (attachedProduct != null)
{
var attachedEntry = db.Entry(attachedProduct);
attachedEntry.CurrentValues.SetValues(model);
}
else //如果不在当前上下文追踪
{
entry.State = EntityState.Modified;
}
}
//db.Entry(model).State = EntityState.Modified;
}
}
//删除
if (!string.IsNullOrEmpty(deletedRows))
{
List<T> deletedList = JsonHelper.DeserializeData<List<T>>(deletedRows);
foreach (var model in deletedList)
{
db.Entry(model).State = EntityState.Deleted;
//db.Sys_Buttons.Remove(btn);//也可以使用这个方法
}
}
db.SaveChanges();//这里提供保存到数据库中
return new { success = true, Message = "保存成功!" };
}
catch (Exception ex)
{
return new { success = false, Message = "保存失败!" };
}
}