gpt4 book ai didi

c# - 构造表达式树导致InvalidPathException

转载 作者:太空狗 更新时间:2023-10-30 01:10:27 25 4
gpt4 key购买 nike

我正在构造一个表达式树 ( Expression<Func<PlainAddress, bool>> predicate ) 以将其传递给 IQueryable.Where HNibernate 执行查询的函数。当我经过时:

 predicate = y => y.Address.City == geoObject.Name;

一切正常。当我经过时:

var x = Expression.Parameter(typeof(PlainAddress));

Expression<Func<PlainAddress, string>> expression = y => y.Address.City;

predicate = Expression.Lambda<Func<PlainAddress, bool>>(
Expression.Equal(
Expression.Invoke(expression, x),
Expression.Constant(geoObject.Name)),
x);

我得到以下异常

Invalid path: 'y.Address.City' 
[.Where(NHibernate.Linq.NhQueryable`1[BPPDicsManager.Domain.Entities.PlainAddress],
Quote((60ee8287-3f42-426a-8c15-41f62f58623c, ) => (String.op_Equality((y, ) =>
(y.Address.City)60ee8287-3f42-426a-8c15-41f62f58623c, p1))), )]

我做错了什么?这两个选项有什么区别?

最佳答案

我不熟悉 NHibernate,但我可以尝试解释这两个表达式之间的差异。

1.主要区别在于Expression.Invoke的使用在示例 # 2 中,它创建了一个 InvocatonExpression,它“表示将委托(delegate)或 lambda 表达式应用于参数表达式列表的表达式”。这引入了一种间接性——松散地说,

样本#1 是:

y => y.Address.City == geoObject.Name;

而示例 # 2 是某事,例如:

x => new Func<PlainAddress, string>(y => y.Address.City).Invoke(x) 
== geoObject.Name

您可以使用 Expression.Property 使第二个样本更接近第一个样本创建适当的 MemberExpression:

var predicate = Expression.Lambda<Func<PlainAddress, bool>>(
Expression.Equal(
Expression.Property(Expression.Property(x, "Address"), "City"),
Expression.Constant(geoObject.Name)),
x);

现在更接近于:

x => x.Address.City == AsStringLiteral(geoObject.Name)

(我猜这足以使谓词与 NHibernate 一起工作。)


2.当然,另一个区别是使用Expression.Constant。在示例 # 2 中,它将急切地评估 geoObject.Name 的值并将其转换为表达式树中的文字。如果您想像示例 # 1 中那样“模拟”geoObject 变量(或者可能是 this?)的提升,您将需要做更多的工作。

关于c# - 构造表达式树导致InvalidPathException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4714676/

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