- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个包,我在其中构建表达式树,通过 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/
我正在尝试根据 QDateTime 对 QList 进行排序,但出现以下错误: must use '.*' or '->*' to call pointer-to-member function in
如何在不使用“<”运算符的情况下递归编写一个方法来检查一个数字是否小于另一个数字? 您只能使用加、减、乘和等于运算符。 它必须是递归的 x 和 y 始终为 0 或更大 应返回 boolean 值 如果
我有一个包,我在其中构建表达式树,通过 PredicateBuilder 与 EntityFramework 一起使用: public Expression> constructaPredicate(
正在尝试编译这段代码 import static org.hamcrest.Matchers.is; import static org.hamcrest.number.OrderingCompari
我正在使用这样的东西: schema.number .lessThan( value, `You own only ${value}.`) 它工
在已弃用的 Criteria API 中,我可以执行以下操作: Object value = myFunc(); //this function returns numeric value based
在 JavaFX 中,有一个 IntegerProperty继承方法的类,例如 greaterThan和 lessThan返回 BooleanBinding .但是,不允许使用空值,因为它将值存储为
我想使用从 map 上获取的边界框按地理点查询文档集合。我有界限: 北:50.730 东:-1.861 南方:50.700 西:-1.893 这是我的实际文档结构(基于我期望它返回的值): docum
WHERE [Date] <= CASE WHEN @param = 1 THEN CONVERT(DATE, GETDATE())
System.Threading.Interlocked 对象允许将加法(减法)和比较作为原子操作。似乎不做相等但同时将 GreaterThan/LessThan 作为原子比较的 CompareExc
我正在尝试使用表达式树编写动态 Linq 2 Sql 查询,但出现异常,提示未为 System.String 和 定义 LessThan 和 GreaterThan 运算符>System.String
我正在尝试创建 Odata 端点,但每当我尝试执行任何涉及日期的查询时都会收到此错误。 我在下面的非常简单示例中重新创建了它。 数据库表 EDMX(片段)
我正在尝试创建 Odata 端点,但每当我尝试执行任何涉及日期的查询时都会收到此错误。 我在下面的非常简单示例中重新创建了它。 数据库表 EDMX(片段)
我是一名优秀的程序员,十分优秀!