Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.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# 多动态列选择表达式树_C#_Linq_Lambda_Expression Trees_System.linq.dynamic - Fatal编程技术网

C# 多动态列选择表达式树

C# 多动态列选择表达式树,c#,linq,lambda,expression-trees,system.linq.dynamic,C#,Linq,Lambda,Expression Trees,System.linq.dynamic,需要:允许用户选择3列从本地数据库返回。在另一篇文章的帮助下,我能够为程序中的不同应用程序返回1列,我想我可以在这里应用相同的过程,但我不知道如何允许用户在同一个查询中选择多个列。我看到whereFunc最多可以接受17个重载,其中除一个外,所有字段都可以是字段,但这似乎不是正确的方法 示例: private static IQueryable<TResult> GraphFields<T, a, b, c, TResult>(IQueryable<T>

需要:允许用户选择3列从本地数据库返回。在另一篇文章的帮助下,我能够为程序中的不同应用程序返回1列,我想我可以在这里应用相同的过程,但我不知道如何允许用户在同一个查询中选择多个列。我看到where
Func
最多可以接受17个重载,其中除一个外,所有字段都可以是字段,但这似乎不是正确的方法

示例:

    private static IQueryable<TResult> GraphFields<T, a, b, c, TResult>(IQueryable<T> query, string aField, string bField, string cField)
    {
        var param = Expression.Parameter(typeof(T), "e");
        Expression aFieldBody = Expression.PropertyOrField(param, aField);
        if (aFieldBody.Type != typeof(TResult))
            aFieldBody = Expression.Convert(aFieldBody, typeof(TResult));
        Expression bFieldBody = Expression.PropertyOrField(param, bField);
        if (bFieldBody.Type != typeof(TResult))
            bFieldBody = Expression.Convert(bFieldBody, typeof(TResult));
        Expression cFieldBody = Expression.PropertyOrField(param, cField);
        if (cFieldBody.Type != typeof(TResult))
            cFieldBody = Expression.Convert(cFieldBody, typeof(TResult));
        
        var lambdaA = Expression.Lambda<Func<T, TResult>>(aFieldBody, param);
        var lambdaB = Expression.Lambda<Func<T, TResult>>(bFieldBody, param);
        var lambdaC = Expression.Lambda<Func<T, TResult>>(cFieldBody, param);

        return query.Select(lambdaA, lambdaB, lambdaC);


    }
TableX有以下列: A、 B、C、D、E、F

A B C D E F
1 2 6 2 4 6
3 6 2 7 2 1
4 8 0 3 7 6
用户选择A、D、F列

查询应返回:

1 2 6
3 7 1
4 3 6
实现这一点的SQL语句如下所示:

col1 = user selection 1.SelectedItem.ToString();
col2 = user selection 2.SelectedItem.ToString();
col3 = user selection 3.SelectedItem.ToString();


SELECT @col1, @ col2, @col3 FROM TableX;
var list = conn.Table<Table1>()
        .Where(t => t.User_ID == user).Distinct().ToList();

var listquery = list.AsQueryable();
        var Values = listquery
                .Select("new {Field1}")
                .ToDynamicList();
如果我知道在运行时之前要选择的字段,Linq语句将类似于以下内容:

(from UserPageTbl in conn.Table<TableX>()
                         select new
                         {
                             TableX.A,
                             TableX.B,
                             TableX.C,
                         }

                       ).ToList();
问题:我不知道如何向lambda表达式添加额外的列以返回多个选定列

尝试将Select查询lambda表达式中的项组合起来,如上所述:

    private static IQueryable<TResult> GraphFields<T, a, b, c, TResult>(IQueryable<T> query, string aField, string bField, string cField)
    {
        var param = Expression.Parameter(typeof(T), "e");
        Expression aFieldBody = Expression.PropertyOrField(param, aField);
        if (aFieldBody.Type != typeof(TResult))
            aFieldBody = Expression.Convert(aFieldBody, typeof(TResult));
        Expression bFieldBody = Expression.PropertyOrField(param, bField);
        if (bFieldBody.Type != typeof(TResult))
            bFieldBody = Expression.Convert(bFieldBody, typeof(TResult));
        Expression cFieldBody = Expression.PropertyOrField(param, cField);
        if (cFieldBody.Type != typeof(TResult))
            cFieldBody = Expression.Convert(cFieldBody, typeof(TResult));
        
        var lambdaA = Expression.Lambda<Func<T, TResult>>(aFieldBody, param);
        var lambdaB = Expression.Lambda<Func<T, TResult>>(bFieldBody, param);
        var lambdaC = Expression.Lambda<Func<T, TResult>>(cFieldBody, param);

        return query.Select(lambdaA, lambdaB, lambdaC);


    }
我尝试了以下方法,因为我认为多个重载将允许我

var lambda = Expression.Lambda<Func<T,a,b, TResult>>(aFieldBody, bFieldBody, cFieldBody, param);
var lambda=Expression.lambda(aFieldBody,bieldbody,cFieldBody,param);
我还研究了将其添加到PropertyOrField中,但它只接受两个重载:一个用于参数表达式,一个用于字段名。我就是不知道如何添加更多的列

尝试通过执行以下操作来使用Linq.Dynamic.Core:

col1 = user selection 1.SelectedItem.ToString();
col2 = user selection 2.SelectedItem.ToString();
col3 = user selection 3.SelectedItem.ToString();


SELECT @col1, @ col2, @col3 FROM TableX;
var list = conn.Table<Table1>()
        .Where(t => t.User_ID == user).Distinct().ToList();

var listquery = list.AsQueryable();
        var Values = listquery
                .Select("new {Field1}")
                .ToDynamicList();
var list=conn.Table()
.Where(t=>t.User_ID==User).Distinct().ToList();
var listquery=list.AsQueryable();
var Values=listquery
.Select(“新建{Field1}”)
.ToDynamicList();
我得到以下例外情况: 引发System.TypeInitializationException异常 的类型初始值设定项
System.Linq.Dynamic.Core.Parser.EnumerationsFromMscorlib引发了异常。

您正在做一些事情,但不知道以后如何使用它。最好添加用例。也许我可以提出解决办法。这里的基本问题是,每个这样的投影都需要类。LINQ是围绕静态编译时类型设计的。匿名类型不是在运行时创建的,虽然可以这样做,但很难使用它们。创建运行时匿名类型和查询的一种简单方法是使用和字符串查询。@NetMage我按照建议尝试了使用System.Linq.Dynamic.Core。我已经在上面尝试过的东西中添加了这个。我不确定我是否正确设置了“IQueryable”,因为我收到了“System.Linq.Dynamic.Core.Parser.EnumerationsFromMScorlib”的“TypeInitializationException”错误。为什么要使用
ToList
初始化
列表
?只需将
listquery
设置为不带
ToList
的表达式,然后在
listquery
上执行
Select
。不确定这是否仍然相关,但听起来像是动态LINQ库中的错误。