【发布时间】:2014-12-08 21:00:05
【问题描述】:
我正在尝试制作一个灵活的导出器,以从通过 LINQ to SQL 访问的 SQL 数据库中导出信息,从而程序可以动态选择要选择的字段并在服务器端执行所有处理。
最终目标是有一个简单的语句,如:
var result = db.Product.Select(p => selector(p));
其中选择器是动态创建的表达式树,描述要选择的字段。目前,我将每个 db 字段分配给它自己的单独选择器,例如:
Expression<Func<Product, string>> name = p => p.Name;
Expression<Func<Product, string>> createdAt = p => p.createdAt.ToString();
目前,我正在获取所选字段并尝试从中创建一个连接表达式,该表达式从 select 语句返回逗号分隔的字符串结果,例如:
Expression<
Func<
Func<Product, string>,
Func<Product, string>,
Func<Product, string>>> combinator = (a, b) => (p) => a(p) + "," + b(p);
// So I can do something like...
Expression<Func<Product, string>> aggregate = p => "";
foreach (var field in fieldsToSelect)
aggregate = combinator(aggregate, field);
// This would create...
Expression<Func<Products, string>> aggregate = p => a(p) + "," + b(p);
一旦我用很多字段建立了我的选择器,我就可以在语句中执行它,所有的处理都在服务器上完成。但是,我无法正确地创建一个表达式来连接两个子函数,以使结果不是在往返行程后简单地执行以获取结果的 Func:
var joinedSelector = combinator.Compile();
Func<Products, string> result = joinedSelector(firstSelector.Compile(), secondSelector.Compile());
var query = db.Product.Select(p => result(p)).ToList();
根据我对表达式树的有限理解,这实际上并不会产生一个,因为语句被编译为正常的 Funcs。我看过 Expression.Coalesce() 但不确定它是否是我所追求的(认为它只是“??”)。
我对这类东西还很陌生,如果有任何帮助,我将不胜感激。
即使人们可以想出更好的方法来解决原始问题,我仍然很想解释一下如何实现我正在尝试做的事情,只是为了学习如何使用表达式树。
【问题讨论】:
-
我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
标签: c# linq-to-sql lambda expression func