Unc*_*aul 5 .net linq nhibernate performance
我最近解决了在运行时动态创建Linq表达式的问题.我发现的大多数示例都处理了将给定数据库实体的一个属性与单个参数进行比较的相当简单的任务.像这样:
Session.Query.Where(m => m.Name.Contains("test"))
Run Code Online (Sandbox Code Playgroud)
使用更通用的方法也可以实现这一点:
var item = Expression.Parameter(typeof (MyClass), "item");
var property = Expression.Property(item, "Name");
var containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var searchExpression = Expression.Constant(searchString, typeof(string));
var containsMethodExpression = Expression.Call(property, containsMethod, searchExpression);
var lambda = Expression.Lambda<Func<MyClass, bool>>(containsMethodExpression, item);
query = query.Where(lambda);
Run Code Online (Sandbox Code Playgroud)
但是,有时候任务有点复杂,人们希望获得如下内容:
Session.Query.Where(m => m.SpecialProperty.Any(f => f.Name.Contains("test")));
Run Code Online (Sandbox Code Playgroud)
其中"SpecialProperty"的类型为List <>,属性"Name"的类型为string.
是否可以动态构建这样的Linq表达式,如何实现?这种方法是否有任何性能问题?
找到了一个在我的特定用例中工作的解决方案,并且完全符合我的要求.
/*
building expression tree
example: Session.Query.Where(m => m.SpecialProperty.Any(f => f.Name.Contains("test")))
*/
var innerItem = Expression.Parameter(typeof(MyInnerClass), "f");
var innerProperty = Expression.Property(innerItem, "Name");
var innerMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var innerSearchExpression = Expression.Constant(searchString, typeof(string));
var innerMethodExpression = Expression.Call(innerProperty, innerMethod, new[] { innerSearchExpression });
var innerLambda = Expression.Lambda<Func<MyInnerClass, bool>>(innerMethodExpression, innerItem);
var outerItem = Expression.Parameter(typeof(MyOuterClass), "m");
var outerProperty = Expression.Property(outerItem, info.Name);
/* calling a method extension defined in Enumerable */
var outerMethodExpression = Expression.Call(typeof(Enumerable), "Any", new[] { typeof(MyInnerClass) }, outerProperty, innerLambda);
var outerLambda = Expression.Lambda<Func<MyOuterClass, bool>>(outerMethodExpression, outerItem);
query = query.Where(outerLambda);
Run Code Online (Sandbox Code Playgroud)
需要这种相当简陋的方法而不是更优雅的单行LINQ-Expression,以允许类型和方法名称的参数化.但是,我当然不介意有关可能的性能处罚的其他建议和想法.
这段代码片段很可能也有助于解决如何使用非泛型Lambda生成子查询.
归档时间: |
|
查看次数: |
3116 次 |
最近记录: |