如何使用非泛型Lambda生成子查询

时间:2009-09-28 23:37:10

标签: c# lambda

如何将以下通用Lambda函数转换为lambda表达式:

context.AssociateWith<Product>(p => p.Regions.Where(r => r.Country == 'Canada')

我正在尝试创建一个没有任何<T>或直接调用的完整lambda表达式。类似的东西:

void AddFilter(ITable table, MetaDataMember relation)
{
    var tableParam = Expression.Parameter(table.ElementType, "e");
    var prop = Expression.Property(tableParam, relation.Name);
    var func = typeof(Func<,>).MakeGenericType(table.ElementType, relation.type)
    var exp = Expression.Lambda(func, prop, tableParam);
}

这会产生e.Regions ...但我无法从那里得到Where部分......

2 个答案:

答案 0 :(得分:2)

我知道我在游戏中已经很晚了,我的回答很可能这不是您正在寻找的确切解决方案(仍然经常使用),但也许它会帮助您和其他人建立他们的表达:

/* 
example: Session.Query.Where(m => m.Regions.Where(f => f.Name.Equals("test")))
*/ 

var innerItem = Expression.Parameter(typeof(MyInnerClass), "f");
var innerProperty = Expression.Property(innerItem, "Name");
var innerMethod = typeof(string).GetMethod("Equals", 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), "Where", new[] { typeof(MyInnerClass) }, outerProperty, innerLambda);
var outerLambda = Expression.Lambda<Func<MyOuterClass, bool>>(outerMethodExpression, outerItem);
query = query.Where(outerLambda);

根据此处发布的答案:Creating a Linq expression dynamically containing a subquery

答案 1 :(得分:0)

试试这个,它并不漂亮,但它为您提供了整个结构的有效表达式。您可以将内部lambda定义为表达式,但是在将其传递给Where()之前,您仍然需要对其进行编译,因此出于此答案的目的,它似乎是多余的。

Expression<Func<Product, IEnumerable<Region>>> getRegions = 
      p => p.Regions.Where(r => r.Country == "Canada");