C# 多动态列选择表达式树
需要:允许用户选择3列从本地数据库返回。在另一篇文章的帮助下,我能够为程序中的不同应用程序返回1列,我想我可以在这里应用相同的过程,但我不知道如何允许用户在同一个查询中选择多个列。我看到whereC# 多动态列选择表达式树,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>
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库中的错误。