在运行时动态生成谓词
不确定这是否完全可能; 我发现了一些关于表达式和谓词构建器的东西,但到目前为止,没有任何东西可以让你在不事先知道它们的情况下运行任意查询。
基本上,我有一个来自大型SQL数据库的对象集合,我正在构建一个网页(ASP.NET MVC 4),允许用户显示和过滤这些对象。 用户将要输入的查询的复杂程度各不相同。 让他们输入这些查询的最简单和最简单的方法就像Visual Studio TFS插件允许您搜索工作项的方式:条件表,您可以继续添加行。 为连接条件选择“和”或“或”,然后选择一个字段,输入一个值,并选择是否需要与之匹配或不匹配的事物:
1. show items where [Field] [is|is not] [value] 2. [and|or] [Field] [is|is not] [value] 3. [and|or] [Field] [is|is not] [value] etc...
什么是最简单的方法将它变成LINQ-ish我可以坚持一个.ToList()
的结尾? 到目前为止,我提出的唯一解决方案是涉及一个相当大且丑陋的开关块,其中的情况与各种字段匹配并且粘贴在.Where()
,但允许用户选择“或”作为条件然后我最终做了这样的事情:
这看起来不像我想的那么优雅。
你可以这样做:
class Program { public enum Operator { And, Or } public class Condition { public Operator Operator { get; set; } public string FieldName { get; set; } public object Value { get; set; } } public class DatabaseRow { public int A { get; set; } public string B { get; set; } } static void Main(string[] args) { var conditions = new List { new Condition { Operator = Operator.And, FieldName = "A", Value = 1 }, new Condition { Operator = Operator.And, FieldName = "B", Value = "Asger" }, new Condition { Operator = Operator.Or, FieldName = "A", Value = 2 }, }; var parameter = Expression.Parameter(typeof (DatabaseRow), "x"); var currentExpr = MakeExpression(conditions.First(), parameter); foreach (var condition in conditions.Skip(1)) { var nextExpr = MakeExpression(condition, parameter); switch (condition.Operator) { case Operator.And: currentExpr = Expression.And(currentExpr, nextExpr); break; case Operator.Or: currentExpr = Expression.Or(currentExpr, nextExpr); break; default: throw new ArgumentOutOfRangeException(); } } var predicate = Expression.Lambda>(currentExpr, parameter).Compile(); var input = new[] { new DatabaseRow {A = 1, B = "Asger"}, new DatabaseRow {A = 2, B = "Hans"}, new DatabaseRow {A = 3, B = "Grethe"} }; var results = input.Where(predicate).ToList(); } static BinaryExpression MakeExpression(Condition condition, ParameterExpression parameter) { return Expression.Equal( Expression.MakeMemberAccess(parameter, typeof (DatabaseRow).GetMember(condition.FieldName)[0]), Expression.Constant(condition.Value)); } }
这假设您有一个类作为具有正确类型的数据库行的模型。 然后,您可以通过正则表达式将条件解析为上面显示的键入条件列表,并且提供的代码可以将其转换为表达式树。 生成的表达式可以编译和运行(如图所示)或转换为SQL(只是将谓词填充到IQueryable.Where中)。
您可以使用LINQKit中的PredicateBuilder
来执行此操作。 使用其And()
和Or()
扩展方法,您可以为查询构建表达式树 。 然后,您可以使用该表达式树作为Where()
的条件。 您还需要调用AsExpandable()
或您的query
,或者在创建的表达式上调用Expand()
。
您可以使用Dynamic Linq动态添加条件。
见https://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
上述就是C#学习教程:在运行时动态生成谓词分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1015545.html