我试图使用表达式来动态创建比较操作,以与实体框架核心2.2一起使用。
这是查询
new System.Linq.Expressions.Expression.MethodCallExpressionProxy(((Remotion.Linq.QueryableBase<ORMModel.Sale>)tq).Expression).DebugView
.Call System.Linq.Queryable.Where(
.Constant<Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[ORMModel.Sale]>(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[ORMModel.Sale]),
'(.Lambda #Lambda1<System.Func`2[ORMModel.Sale,System.Boolean]>))
.Lambda #Lambda1<System.Func`2[ORMModel.Sale,System.Boolean]>(ORMModel.Sale $Sale) {
$Sale.CreateDT > (System.DateTime).Constant<System.DateTime>(12/25/2018 5:00:00 AM)
}
字符串
这是我得到的错误
System.Data.SqlClient.SqlError
从字符串转换日期和/或时间时转换失败。
我已经在SQL Server Management Studio中直接使用了该日期值,并且它会执行。
任何帮助或线索的无能赞赏。太多的谷歌搜索和无处可去。每个例子都是SQL字符串,而不是动态表达式。
public static Expression GetBinaryExpression<TSource>(string propertyName, int comparer, dynamic valueIn)
{
PropertyInfo pi = GetPropertyInfo<TSource>(propertyName);
Type pt = pi.PropertyType;
var parameter = Expression.Parameter(typeof(TSource), typeof(TSource).Name);
var property = Expression.Property(parameter, propertyName);
dynamic valueTyped;
if (IsNullableType(pt))
{
valueTyped = Convert.ChangeType(valueIn, Nullable.GetUnderlyingType(pt));
}
else
{
valueTyped = Convert.ChangeType(valueIn, pt);
}
var constant = Expression.Constant(valueTyped);
var val = Expression.Convert(constant, pt);
Expression exp = null;
switch (comparer)
{
case 1:
exp = Expression.Equal(property, val);
break;
case 2:
exp = Expression.NotEqual(property, val);
break;
case 3:
exp = Expression.GreaterThan(property, val);
break;
case 4:
exp = Expression.GreaterThanOrEqual(property, val);
break;
case 5:
exp = Expression.LessThan(property, val);
break;
case 6:
exp = Expression.LessThanOrEqual(property, val);
break;
}
if (exp.CanReduce) exp = exp.Reduce();
return Expression.Lambda<Func<TSource, Boolean>>(exp, parameter);
}
private static bool IsNullableType(Type type)
{
return type.IsGenericType &&
type.GetGenericTypeDefinition().Equals(typeof(Nullable<>));
}
型
我希望返回一个漂亮的结果集,而不是一个令人恼火的错误。
2条答案
按热度按时间r7s23pms1#
SQL Server数据类型Map是解决这个问题的方法,根据我的研究,SqlCommand对象依赖于数据类型Map来将SQL数据类型转换为SQL数据类型。
当涉及到DateTime时,使用常量表达式没有帮助,因为它被序列化为这样的字符串格式:
'2020-05-03T14:32:05.000435Z'
例如,生成的SQL看起来像这样:
字符串
如果日期字符串格式是这样的:'' 2020 -05- 03 T14:32:05',那么SQL服务器会很高兴,但是表达式对数据类型非常严格,你不能为DateTime属性传递这个字符串格式。
废话少说,让我们来看看代码:
型
lambda表达式:
型
这样做的技巧,并允许DbSet生成一个sql参数化命令。
一旦使用DbSet执行,生成的IQueryable将是一个带参数的命令。这可以从生成的SQL和数据类型Map中进行验证,现在可以将SQL数据类型转换为SQL数据类型,而不会抛出可怕的“转换日期和/或时间时转换失败字符串”。
yzuktlbb2#
Wizzyno的答案为我解决了这个问题。下面是完整的实现:
字符串
使用...
型