通过动态调用(获取)属性来初始化(实体)对象。实体框架,c#,ASP>NET

Posted

技术标签:

【中文标题】通过动态调用(获取)属性来初始化(实体)对象。实体框架,c#,ASP>NET【英文标题】:Initializing (Entity) object by calling (get) property dynamically. Entity Framework , c#, ASP>NET 【发布时间】:2020-11-30 04:39:59 【问题描述】:

我有以下代码:

public void DBMamLookup(int custid)

    using (LookUpEntities1 lookUp = new LookUpEntities1())
    
        
        var mamconfig = lookUp.MamConfigurations;
        var userlookup = lookUp.UserAccount2_ISO2_3 ;
        
        MamConfiguration obj = mamconfig.Where(m => m.CustID== custid).FirstOrDefault();
        var objNN = lookUp.UserAccount2_ISO2_3.Where(m => m.CustID== custid).Take(15).ToList();            
        
        Type returnType;
        switch (obj.ActiveTableName)
        
            case "MamConfiguration":
                returnType = typeof(MamConfiguration);
                break;                                            
            case "UserAccount1_ISO1_1Billers":                        
                returnType = typeof(UserAccount1_ISO2_3Billers);
                break;                    
            default:
                returnType = typeof(UserAccount2_ISO2_3Billers);
                break;
        
        dynamic que3 = this.GetInstance<dynamic>(obj.ActiveTableName);                
        que3 = lookUp.Set(returnType);
        
        for (int i = 0; i < que3.Local.Count; i++)
        
            Console.WriteLine(que3.Local[i].UserAccount);
               
    
        

我在上面代码的下面一行有问题:

var objNN = lookUp.**UserAccount2_ISO2_3**.Where(m => m.CustID== custid).Take(15).ToList(); 

我必须使其动态化并在运行时调用特定的实体属性。由于我在字符串中有属性名称,即 obj.ActiveTableName 我怎样才能进行如下调用:

var objNN = lookUp.**[obj.ActiveTableName]**.Where(m => m.CustID== custid).Take(15).ToList(); 

【问题讨论】:

你为什么要这样做? 这样的需求出现在我有很多实体表的项目中,实体属性将数据返回到这些表的类型中,并且表有它们单独的属性,如 custid、custname 等。 【参考方案1】:

首先为所有类型创建一个具有通用属性的接口: 例如:

interface IEntityWithCustID

    int CustID  get; set; 

确保所有相关类都实现该接口 例如:

public class UserAccount2_ISO2_3 : IEntityWithCustID

创建一个帮助类来检索数据

static class QueryHelper

    public static List<IEntityWithCustID> GetResult(LookUpEntities1 lookup, string tableName, int custId)
    
        var dbset = lookup.GetType().GetProperty(tableName).GetValue(lookup);
        var entityType = dbset.GetType().GetGenericArguments()[0];
        var method = typeof(QueryHelper).GetMethod(nameof(GetResultInternal)).MakeGenericMethod(entityType);
        return (List<IEntityWithCustID>)method.Invoke(null, new object[]  dbset, custId );
    

    public static List<IEntityWithCustID> GetResultInternal<T>(IDbSet<T> dbset, int custId) where T: class, IEntityWithCustID
    
        return dbset.Where(m => m.CustID == custId).Take(15).ToList().Cast<IEntityWithCustID>().ToList();
    

在您的代码中使用该类(例如)

var res = QueryHelper.GetResult(lookup, obj.ActiveTableName, custid);

还有另一种方法可以创建 Expression.Lambda 以使用 Expression.Lambda 调用创建自定义 lambda 表达式。不过会有点复杂。

【讨论】:

只是关于我建议的解决方案的注释,虽然它“有效”,但有更好的方法来解决这个问题。一种方法是使所有共享公共属性的实体,使用 Table Per Hierarchy 共享一个公共表,并按类型过滤。或者甚至根据您的问题可能有更好的方法。

以上是关于通过动态调用(获取)属性来初始化(实体)对象。实体框架,c#,ASP>NET的主要内容,如果未能解决你的问题,请参考以下文章

如何初始化通过远程方法调用获取的 Hibernate 实体?

实体框架代码迁移 - 卡在初始迁移上

C#winform动态添加控件

实体类的动态生成

Java关于反射

面相对象