gpt4 book ai didi

c# - 使用表达式树调用 Entity Framework 的 .Any 扩展方法

转载 作者:太空宇宙 更新时间:2023-11-03 16:49:32 25 4
gpt4 key购买 nike

我在这里看过几个例子Calling a Method from an ExpressionMSDN但我无法为下面的查询获得 Any() 的正确方法调用/对象类型。我似乎能够获得属性调用,但不能获得子属性的 IEnumerable 部分。
billing_map_set_lu 是 billmaps_lu 的父级,在 Entity Framework 中被定义为关联。

我使用表达式树的原因是我需要能够在运行时使用 1-n .SelectMany(p => p.billmaps_lu).Where(predicate) 子句定义查询。所以我想,如果我可以构建表达式树,我就可以处理这个系统的所有不同组合,其中有很多。

var myResults = ctx.billing_map_set_lu
.Where(p => p.billmaps_lu.Any(b => b.billmap_columnname == "templatesittings_key" && b.billmap_columnvalue == 428264))
SelectMany(p => p.billmaps_lu)
.Where (b =>b.billmap_columnname =="locations_key" && b.billmap_columnvalue == 12445)
Select(z => z.billing_map_set_lu);

我已经使用上面的示例进行了很多尝试...

ParameterExpression bms = Expression.Parameter(typeof(billmaps_lu));
Expression left1 = Expression.Property(bms, typeof(billmaps_lu).GetProperty("billmap_columnname"));
Expression right1 = Expression.Constant("templatesittings_key", typeof(string));
Expression InsideAny1 = Expression.Equal(left1, right1);
Expression left2 = Expression.Property(bms, typeof(billmaps_lu).GetProperty("billmap_columnvalue"));
Expression right2 = Expression.Constant(428264, typeof(int));
Expression InsideAny2 = Expression.Equal(left2, right2);
Expression myWhereClause1 = Expression.AndAlso(InsideAny1, InsideAny2);

上面的部分看起来不错,但是当我尝试执行 .Any 时,就好像我无法获得正确的属性/方法来获取正确的对象。 (我觉得我正在处理一个物理问题,我正在使用错误的单位。)我希望它是我所缺少的简单的东西,我对表达式树很陌生。我已经包含了非工作代码来尝试向您展示我的想法以及有人如何引导我朝着正确的方向前进。

MethodInfo method = typeof(Enumerable).GetMethods().Where(m => m.Name == "Any" && m.GetParameters().Length == 2).Single().MakeGenericMethod(typeof(billing_map_set_lu).GetProperty("billmaps_lu").PropertyType);
ParameterExpression billMapSetParameter = Expression.Parameter(typeof(billing_map_set_lu), "p");
ParameterExpression billMaps = Expression.Parameter(typeof(billmaps_lu), "p1");
var myFunction = Expression.Lambda<Func<billmaps_lu, bool>>(Expression.Call(method, Expression.Property(billMapSetParameter, typeof(billing_map_set_lu).GetProperty("billmaps_lu")), myWhereClause1), billMaps)

最佳答案

免责声明,我没有任何已编译的工作代码。

2 个问题。

第一个问题大概在于:

ParameterExpression billMapSetParameter = Expression.Parameter(typeof(billing_map_set_lu), "p");

这不是您需要的参数:

Expression.Lambda<Func<billmaps_lu, bool>>(Expression.Call(method, Expression.Property(**billMapSetParameter**, typeof(billing_map_set_lu).GetProperty("billmaps_lu")), myWhereClause1), billMaps)

将 billMapSetParameter 更改为 billMaps ParamterExpression,然后就可以开始了。您正在调用 PropertyExpression 以从 ParameterExpression 为您获取 billMapSet。

第二个问题:(不确定,但我的直觉)您可能需要将 Where 子句作为类型为 Expression<.Func<>> 的 ConstantExpression 传递。 .任何方法都有两个参数,其中第二个是一个 Expression<.Func<>>(或者只是一个 Func<>?不记得了)。

var whereExpression = Expression.Lambda<.Func<.billmaps_lu, bool>>(myWhereClause1, bms);
var ce = Expression.Constant(whereExpression)

然后将 ce 传回原来你“myWhereClause1”所在的位置。

交叉手指它有效

编辑 - 废掉那个,SHOW MI ZEH CODEZ

public class Foo
{
public List<string> Strings { get; set; }
}

class Program
{
static void Main(string[] args)
{
Func<Foo, bool> func =
a => a.Strings.Any(b => b == "asdf");

// b => b == "asdf";
var bParameter = Expression.Parameter(typeof (string));
var asdfConstant = Expression.Constant("asdf");
var compare = Expression.Equal(bParameter, asdfConstant);
var compareExpression = Expression.Lambda<Func<string, bool>>(compare, bParameter);
var ceCompareExpression = Expression.Constant(compareExpression.Compile());

// a => a.Strings.Any(compareExpression)
var parameter = Expression.Parameter(typeof (Foo));

var foosProperty = Expression.Property(parameter, typeof (Foo).GetProperty("Strings"));
MethodInfo method = typeof(Enumerable).GetMethods().Where(m => m.Name == "Any" && m.GetParameters().Length == 2).Single().MakeGenericMethod(typeof(string));

var anyMethod = Expression.Call(method, foosProperty, ceCompareExpression);

var lambdaExpression = Expression.Lambda<Func<Foo, bool>>(anyMethod, parameter);

// Test.
var foo = new Foo {Strings = new List<string> {"asdf", "fdsas"}};

Console.WriteLine(string.Format("original func result: {0}", func(foo)));
Console.Write(string.Format("constructed func result: {0}", lambdaExpression.Compile()(foo)));

Console.ReadKey();
}
}

关于c# - 使用表达式树调用 Entity Framework 的 .Any 扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4549012/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com