Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架6的多对多通用更新方法_C#_Entity Framework_Orm_Dependency Injection_Entity Framework 6 - Fatal编程技术网

C# 实体框架6的多对多通用更新方法

C# 实体框架6的多对多通用更新方法,c#,entity-framework,orm,dependency-injection,entity-framework-6,C#,Entity Framework,Orm,Dependency Injection,Entity Framework 6,对于抽象的数据库操作类中的实体框架,我有一个通用的Update方法: public virtual void Update(T updatedObject, int key) { if (updatedObject == null) { return; } using (var databaseContext = new U()) { databaseContext.Database.Log = Console.Write

对于抽象的数据库操作类中的实体框架,我有一个通用的
Update
方法:

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

但是,这种覆盖将在继承自
数据库操作的所有类中扩散,并具有trusset对象。我是否可以将添加的两行注入到泛型更新方法中,以便为更新方法提供集合属性,加载它们,并将相应的更新集合应用于该实体?提前感谢。

查看您的代码,您会想到以下几点:

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();
    }
}
公共虚拟无效更新(T updateObject,int key,params string[]navigationProperties){
if(updateObject==null){
返回;
}
使用(var databaseContext=new U()){
databaseContext.Database.Log=Console.Write;
T foundEntity=databaseContext.Set().Find(键);
var entry=databaseContext.entry(foundEntity);
entry.CurrentValues.SetValues(updateObject);
foreach(navigationProperties中的var prop){
var collection=entry.collection(prop);
collection.Load();
collection.CurrentValue=typeof(T).GetProperty(prop).GetValue(updateObject);
}
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();
    }
}
公共虚拟void更新(T updateObject,int key,params Expression[]navigationProperties){
if(updateObject==null){
返回;
}
使用(var databaseContext=new U()){
databaseContext.Database.Log=Console.Write;
T foundEntity=databaseContext.Set().Find(键);
var entry=databaseContext.entry(foundEntity);
entry.CurrentValues.SetValues(updateObject);
foreach(navigationProperties中的var prop){
字符串成员名;
var member=prop.Body作为MemberExpression;
如果(成员!=null)
memberName=member.member.Name;
else抛出新异常(“其中一个navigationProperties不是成员访问表达式”);
var collection=entry.collection(memberName);
collection.Load();
collection.CurrentValue=typeof(T).GetProperty(memberName).GetValue(UpdateObject);
}
databaseContext.SaveChanges();
}
}

谢谢,你能举个表达式的例子吗?具体地说,我发现我需要在更新方法签名中为ICollection设置一个参数:
公共虚拟无效更新(T updateObject,int key,list)我可能已经通过使用
对象解决了这个问题。但是对于表达式,我如何更新
类型(T).GetProperty(prop).GetValue(updateObject);
?我的意思有点不同-使用表达式以更安全的方式传递导航属性名称。请看这里的示例,了解如何从成员访问表达式获取属性名称。@ScottH用使用表达式的示例代码更新了我的答案。这能处理嵌套集合导航属性吗?我遇到了这个问题。So它适用于trusset.Seals,但不适用于TrussInstance,TrussInstance具有导航属性trusset,trusset随后具有一个密封的导航集合。它抛出一个
参数异常
:“类型“TrussInstance”上的属性“Seals”不是导航属性。引用和收集方法只能与导航属性一起使用。请使用属性或ComplexProperty方法。”
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();
    }
}