gpt4 book ai didi

c# - 在字符串上构建表达式时如何实现 LessThan 等

转载 作者:太空狗 更新时间:2023-10-29 20:20:26 25 4
gpt4 key购买 nike

我有一个包,我在其中构建表达式树,通过 PredicateBuilder 与 EntityFramework 一起使用:

public Expression<Func<T, bool>> constructaPredicate<T>(ExpressionType operation, string fieldName, Expression value)
{
var type = typeof(T);
var parameter = Expression.Parameter(type);
var member = Expression.PropertyOrField(parameter, fieldName);
Expression comparison = Expression.MakeBinary(operation, member, value);
var expression = Expression.Lambda<Func<T, bool>>(comparison, parameter);
return expression;
}

这工作正常,除了将字符串与 GreaterThan 等进行比较时。在那种情况下,我得到一个异常:

The binary operator GreaterThan is not defined for the types 'System.String' and 'System.String'.

这很简单。浏览了一下,我只发现了一些关于这个问题的引用,而且在我正在做的事情的背景下没有一个。

当然,问题在于没有 String.GreaterThan 方法。通常的答案是使用 String.CompareTo(),但我还没有想出如何实现它。

我一直在尝试使用带有 methodinfo 对象的 Expression.MakeBinary 重载,但我还没有弄明白。

帮忙吗?

已添加

所以,我尝试了特殊情况的 String.GreaterThan 等,但我仍然遇到同样的错误:

Expression comparison = null;

if (value.Type == typeof (string))
{
if (operation == ExpressionType.GreaterThanOrEqual ||
operation == ExpressionType.GreaterThan ||
operation == ExpressionType.LessThanOrEqual ||
operation == ExpressionType.LessThan)
{
var method = value.Type.GetMethod("CompareTo", new[] {typeof (string)});
var zero = Expression.Constant(0);

var result = Expression.Call(member, method, converted);

comparison = Expression.MakeBinary(operation, result, zero);
}
}

if (comparison == null)
comparison = Expression.MakeBinary(operation, member, converted);

var lambda = Expression.Lambda<Func<T, bool>>(comparison, parameter);

但我仍然看到完全相同的异常。这对我来说毫无意义,因为如果我正在做我认为我正在做的事情,表达式中唯一的 GreaterThan 就是比较 Int32 和 Int32。

更多内容

从表达式树中删除 GreaterThan 后,我发现我会看到同样的错误,这很奇怪。

我一直在运行这段代码作为单元测试的一部分, Entity Framework 连接到一个名为 Effort 的内存数据库。 .所以我针对 SqlServer 进行了尝试。

我的原始代码没有特殊大小写的字符串,但对所有内容都使用 GreaterThan,在针对 SqlServer 运行时以及针对 Effort 运行时抛出“GreaterThan not defined”异常。

我修改过的代码,那个特殊大小写的字符串,在 SqlServer 上运行得很好,但在运行 Effort 时抛出了“GreaterThan not defined”异常。

似乎当 Effort 在表达式树中看到 CompareTo() 时,它会将其转换为 GreaterThan,这会导致我们熟悉的异常。

还有更多

在继续探索这个问题的过程中,我确定 Effort 中存在一个错误,可以通过一个非常简单的示例来揭示:

var foos = myDbContext.Foos.Where(f => f.fooid.CompareTo("Z") > 0).ToList();

这很好用,当 myDbContext 连接到 SqlServer 数据库时,它会在连接到 Effort 数据库时抛出我们最喜欢的异常。我已经在 Effort 讨论论坛上提交了错误报告。

对于那些正在阅读本文的人,我在上面的第一个“添加”部分中的第二次尝试是正确的解决方案。它适用于 SqlServer,但它不适用于 Effort 是由于 Effort 中的错误。

附录

问题是,上面的“converted”指的是什么。

说实话,我几乎不记得了。

在我的代码中发生的事情是,我有一个正在应用这些比较的表达式树。我正在使用 Expression.Convert() 将其转换为基础类型。

我不确定完整的方法是否有意义,缺少类(class)的其余部分,但这里是:

public Expression<Func<T, bool>> constructSinglePredicate<T>(object context)
{
var type = typeof(T);
var parameter = Expression.Parameter(type);
var member = this.getMember<T>(type, parameter);
var value = this.constructConstantExpression<T>(this.rightHandSide, context);
ExpressionType operation;
if (!operationMap.TryGetValue(this.selectionComparison, out operation))
throw new ArgumentOutOfRangeException("selectionComparison", this.selectionComparison, "Invalid filter operation");

try
{
var converted = (value.Type != member.Type)
? (Expression)Expression.Convert(value, member.Type)
: (Expression)value;

Expression comparison = null;

if (value.Type == typeof(string))
{
if (operation == ExpressionType.GreaterThanOrEqual ||
operation == ExpressionType.GreaterThan ||
operation == ExpressionType.LessThanOrEqual ||
operation == ExpressionType.LessThan)
{
MethodInfo method = value.Type.GetMethod("CompareTo", new[] { typeof(string) });
var zero = Expression.Constant(0);
var result = Expression.Call(member, method, converted);
comparison = Expression.MakeBinary(operation, result, zero);
}
}

if (comparison == null)
comparison = Expression.MakeBinary(operation, member, converted);

var lambda = Expression.Lambda<Func<T, bool>>(comparison, parameter);

return lambda;
}
catch (Exception)
{
throw new InvalidOperationException(
String.Format("Cannot convert value \"{0}\" of type \"{1}\" to field \"{2}\" of type \"{3}\"", this.rightHandSide,
value.Type, this.fieldName, member.Type));
}
}

最佳答案

这个有效:

Expression comparison = null;

if (value.Type == typeof (string))
{
if (operation == ExpressionType.GreaterThanOrEqual ||
operation == ExpressionType.GreaterThan ||
operation == ExpressionType.LessThanOrEqual ||
operation == ExpressionType.LessThan)
{
var method = value.Type.GetMethod("CompareTo", new[] {typeof (string)});
var zero = Expression.Constant(0);

var result = Expression.Call(member, method, converted);

comparison = Expression.MakeBinary(operation, result, zero);
}
}

if (comparison == null)
comparison = Expression.MakeBinary(operation, member, converted);

var lambda = Expression.Lambda<Func<T, bool>>(comparison, parameter);

关于c# - 在字符串上构建表达式时如何实现 LessThan 等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24814278/

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