我有一个通用的 Update
抽象 Entity Framework 的方法 DatabaseOperations<T,U>
类:
public virtual void Update(T updatedObject, int key)
{
if (updatedObject == null)
{
return;
}
using (var databaseContext = new U())
{
databaseContext.Database.Log = Console.Write;
T foundEntity = databaseContext.Set<T>().Find(key);
databaseContext.Entry(foundEntity).CurrentValues.SetValues(updatedObject);
databaseContext.SaveChanges();
}
}
但是,这不能处理多对多关系。
这个多对多的更新问题可以通过覆盖 Update
来解决。 TrussSetDatabaseOperations : DatabaseOperations<TrussSet, TrussManagementDatabaseContext>
中的方法阅读如下:
public override void Update(TrussSet updatedTrussSet, int key)
{
if (updatedTrussSet == null)
{
return;
}
using (var databaseContext = new TrussManagementDatabaseContext())
{
databaseContext.Database.Log = Console.Write;
TrussSet foundTrussSet = databaseContext.TrussSets.Find(key);
databaseContext.Entry(foundTrussSet).CurrentValues.SetValues(updatedTrussSet)
// Update the many-to-many relationship of TrussSets to Seals
databaseContext.Entry(foundTrussSet).Collection(trussSet => trussSet.Seals).Load();
databaseContext.Entry(foundTrussSet).Collection(trussSet => trussSet.Seals).CurrentValue = updatedTrussSet.Seals;
databaseContext.SaveChanges();
}
}
但是,这种覆盖会扩散到所有继承自 DatabaseOperations
的类中并有一个 TrussSet 对象。我能否以某种方式将添加的两行注入(inject)通用更新方法,以便为更新方法提供集合属性、加载它们并将相应的更新集合应用于该实体?提前致谢。
最佳答案
查看您的代码,想到以下内容:
public virtual void Update(T updatedObject, int key, params string[] navigationProperties) {
if (updatedObject == null) {
return;
}
using (var databaseContext = new U()) {
databaseContext.Database.Log = Console.Write;
T foundEntity = databaseContext.Set<T>().Find(key);
var entry = databaseContext.Entry(foundEntity);
entry.CurrentValues.SetValues(updatedObject);
foreach (var prop in navigationProperties) {
var collection = entry.Collection(prop);
collection.Load();
collection.CurrentValue = typeof(T).GetProperty(prop).GetValue(updatedObject);
}
databaseContext.SaveChanges();
}
}
如果您想要更高的类型安全性,您也可以使用表达式而不是字符串(然后从这些表达式中提取属性名称)。
更新:这里是我在这种情况下所说的“使用表达式”的意思:
public virtual void Update(T updatedObject, int key, params Expression<Func<T, IEnumerable>>[] navigationProperties) {
if (updatedObject == null) {
return;
}
using (var databaseContext = new U()) {
databaseContext.Database.Log = Console.Write;
T foundEntity = databaseContext.Set<T>().Find(key);
var entry = databaseContext.Entry(foundEntity);
entry.CurrentValues.SetValues(updatedObject);
foreach (var prop in navigationProperties) {
string memberName;
var member = prop.Body as MemberExpression;
if (member != null)
memberName = member.Member.Name;
else throw new Exception("One of the navigationProperties is not a member access expression");
var collection = entry.Collection(memberName);
collection.Load();
collection.CurrentValue = typeof (T).GetProperty(memberName).GetValue(updatedObject);
}
databaseContext.SaveChanges();
}
}
关于c# - Entity Framework 6 的多对多通用更新方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32830764/