如何才能在动态 LINQ 中使用动态 Lambda
在搜索表达式解析器时,我发现了 动态 LINQ API。我想使用此 API 让最终用户指定一些用于验证业务对象的标准。
所以我第一次尝试使用该库通过以下单元测试成功
var x = Expression.Parameter(typeof(int), "x");
var list = Expression.Parameter(typeof(List<int>), "list");
var e = DynamicExpression.ParseLambda(new[] { x, list }, null, "list.Any(it == x)");
var compiledExpression = e.Compile();
var myList = new List<int> { 24, 46, 67, 78 };
Assert.AreEqual(false, compiledExpression.DynamicInvoke(2, myList));
Assert.AreEqual(true, compiledExpression.DynamicInvoke(24, myList));
但是我想要一个稍微复杂的语法,因为我想将其更改
list.Any(it == x) // OK
为
list.Any(i => i == x) // Raises error: No property or field 'i' exists in type 'int'
第二个语法但是允许我像这样嵌套 lambda(这是我的最终目标) :
list1.All(i => list2.Any(j => j == i))
有人知道如何调整Dynamic.cs以支持这种语法吗?
In my search for a expression parser, I found the Dynamic LINQ API. I want to use this API for letting the end user specify some criteria for validation of the business objects.
So my first attempt to use the library succeeds with the following Unit test
var x = Expression.Parameter(typeof(int), "x");
var list = Expression.Parameter(typeof(List<int>), "list");
var e = DynamicExpression.ParseLambda(new[] { x, list }, null, "list.Any(it == x)");
var compiledExpression = e.Compile();
var myList = new List<int> { 24, 46, 67, 78 };
Assert.AreEqual(false, compiledExpression.DynamicInvoke(2, myList));
Assert.AreEqual(true, compiledExpression.DynamicInvoke(24, myList));
However I want to have a slightly more complex syntax as I want to change this
list.Any(it == x) // OK
into
list.Any(i => i == x) // Raises error: No property or field 'i' exists in type 'int'
The second syntax would however allow me to nest lambda's (which is my ultimate goal) like so:
list1.All(i => list2.Any(j => j == i))
Anyone know how to adjust Dynamic.cs to support this syntax?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
经过几个小时的调试,我自己找到了解决方案。
以下单元测试现已成功:
我已对示例 Dynamic.cs 文件应用的更改:
1) 使用成员“Lambda”扩展枚举 TokenId
2) 将名为“internals”的 IDictionary 添加到类 ExpressionParser。在 ExpressionParser 构造函数中对其进行初始化
3) 替换(从第 971 行开始)
为
4) 替换(从第 1151 行开始)
为
5) 替换(从第 1838 行开始)
为
After some hours of debugging I found the solution myself.
The following unit test succeeds now:
The changes I have applied to the example Dynamic.cs file:
1) Extend the enum TokenId with the member 'Lambda'
2) Add an IDictionary named internals to class ExpressionParser. Initialize it in the ExpressionParser constructor
3) Replace (starting on line 971)
with
4) Replace (starting on line 1151)
with
5) Replace (starting on line 1838)
with