使用system.linq.dynamic联接表

问题描述 投票:0回答:1

是否有一种方法可以使用system.linq.dynamic使用表名的字符串连接表?

这似乎是基本的,但所有谷歌搜索指向扩展linq功能的一些极其复杂的答案,似乎我只是缺少一些简单的东西。

我的应用程序允许人们通过从多个表中动态添加条件和字段来在数据上构建过滤器。

我有一个ArrayList字段,格式为“ TableName.FieldName”

我有一个名为Table1的主表,如果其中包含任何其他表,它必须使用主键联接回Table1。

使用system.linq.dynamic构建where子句似乎非常容易。

var query = dbcontext.Table1;
Dictionary<string, ArrayList> reportTables; //store table and its respective field names as an array
query.Select(string.Join(",", reportTables["Table1"].ToArray()));

但是现在我如何轻松地加入子表?

我从循环遍历表开始,如果它不是主表,我想这样添加联接:

  if(reportTables.Keys.Count > 1){
                    // add joins
                    foreach(string tblName in reportTables.Keys)
                    {
                        if(tblName != "Table1")
                        {
                            query.Join(tblName, "Table1.IDField", tblName + ".Table1IDField")
                        }
                    }
                }
entity-framework linq linq-to-sql linq-to-entities
1个回答
0
投票

您可以使用反射从DataContext中检索表。

定义了这些扩展方法:

public static class ObjectExt {
    public static object GetValue(this object obj, string memberName) =>
        obj.GetType().GetPropertyOrField(memberName).GetValue(obj);

    public static TRes GetValue<TRes>(this object obj, string memberName) =>
        obj.GetType().GetPropertyOrField(memberName).GetValue<TRes>(obj);
}

public static class MemberInfoExt {
    public static object GetValue(this MemberInfo member, object srcObject) {
        switch (member) {
            case FieldInfo mfi:
                return mfi.GetValue(srcObject);
            case PropertyInfo mpi:
                return mpi.GetValue(srcObject);
            case MethodInfo mi:
                return mi.Invoke(srcObject, null);
            default:
                throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo or MethodInfo", nameof(member));
        }
    }
    public static T GetValue<T>(this MemberInfo member, object srcObject) => (T)member.GetValue(srcObject);
}

public static class TypeExt {
    public static MemberInfo GetPropertyOrField(this Type t, string memberName, BindingFlags bf = BindingFlags.Public | BindingFlags.Instance) =>
        t.GetMember(memberName, bf).Where(mi => mi.MemberType == MemberTypes.Field || mi.MemberType == MemberTypes.Property).Single();
}

您可以做:

if (reportTables.Keys.Count > 1) {
    // add joins
    foreach (string tblName in reportTables.Keys) {
        if (tblName != "Table1") {
            query.Join(dbcontext.GetValue<IEnumerable>(tblName), "Table1.IDField", tblName + ".Table1IDField")
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.