实体框架多对多通用更新
本文关键字:更新 框架 实体 | 更新日期: 2023-09-27 18:27:24
我正在尝试使用EF6实现一个通用的多对多更新方法。每次我尝试更新导航属性时,我都会得到一个异常:
"违反PRIMARY KEY约束'PK_dbo.Classes'。无法插入对象"dbo.Classes"中存在重复键。重复键值为(698d5483-eb48-4d7e-84e7-a9f95a243d3d)。''''r''n声明已经终止。"
我该怎么修?
public void Update(T entity, params Expression<Func<T, IEnumerable>>[] navProps)
{
using (var context = new Context())
{
T foundEntity = context.Set<T>().Find(entity.Id);
var entry = context.Entry(foundEntity);
entry.CurrentValues.SetValues(entity);
foreach (var prop in navProps)
{
string memberName;
var member = prop.Body as MemberExpression;
if (member != null)
{
memberName = member.Member.Name;
}
else
{
throw new Exception();
}
var collection = entry.Collection(memberName);
collection.Load();
collection.CurrentValue = typeof(T).GetProperty(memberName).GetValue(entity);
}
context.SaveChanges();
}
}
最后,我找到了一个通用多对多更新的解决方案
public void Update(Guid id, T record)
{
using (var context = new FortisDataStoreContext(_client, _user))
{
var set = context.Set<T>().AsQueryable();
foreach (var x in GetNavigationProperties(context, record))
{
foreach (var xx in x.PropertyType.GetGenericArguments())
{
set = set.Include(x.Name);
}
}
var entry = set.FirstOrDefault(x => x.Id == id && x.IsClosed == false);
context.Entry(entry).CurrentValues.SetValues(record);
foreach (var x in GetNavigationProperties(context, record))
{
if(x.PropertyType.GetGenericArguments().Count() > 0)
{
var genericType = x.PropertyType.GenericTypeArguments[0];
var newValues = (IList)x.GetValue(record, null) ?? new object[0];
var genericList = CreateList(genericType);
foreach (var item in newValues)
{
var ident = item.GetType().GetProperty("Id").GetValue(item, null);
var obj = context.Set(genericType).Find(ident);
genericList.Add(obj);
}
context.Entry(entry).Collection(x.Name).CurrentValue = genericList;
}
}
context.SaveChanges();
}
}