许多一对多通用更新与实体框架6法 [英] Many-To-Many Generic Update Method with Entity Framework 6

查看:199
本文介绍了许多一对多通用更新与实体框架6法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有实体框架的通用更新法的抽象 DatabaseOperations< T,U> 类:

I have a generic Update method for Entity Framework in an abstract DatabaseOperations<T,U> class:

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



然而,这不处理多到多关系。

However, this does not handle many-to-many relationships.

这多到很多更新的问题可以通过在更新方法来克服> TrussSetDatabaseOperations:DatabaseOperations< TrussSet,TrussManagementDatabaseContext> 如下:

This many-to-many update problem can be overcome by overriding the Update method in TrussSetDatabaseOperations : DatabaseOperations<TrussSet, TrussManagementDatabaseContext> to read as follows:

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对象。我能以某种方式注入加入两行通用的更新方法,以便更新方法给出集合属性,加载它们,并相应更新集合适用于实体? 。在此先感谢

However, this overriding would proliferate through all the classes that inherit from DatabaseOperations and have a TrussSet object. Can I somehow inject the added two lines into the generic update method, so that the update method is given the collection properties, loads them, and applies the respective updated collection to that entity? Thanks in advance.

推荐答案

看你的代码,以下想到的:

Looking at your code, the following comes to mind:

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

您也可以使用表达式不是字符串(然后如果你想要更多的类型安全提取这些表达式属性名称)

You can also use Expressions instead of strings (and then extract property names from those expressions) if you want more type-safety.

更新:这里是我的意思是在这种情况下,使用表达式

Update: here is what I mean by "use Expressions" in this case:

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

这篇关于许多一对多通用更新与实体框架6法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆