c# - Expression.Convert() 对于 EF Core 中的日期时间数据类型无法正常工作
问题描述
在 .Net 标准 2.0 项目中,我使用的是Microsoft.EntityFrameworkCore nuget version 2.2.6。我正在动态创建 lambda 表达式,如下所示:
//EntityUtility.ConvertToType() converts string to DateTime type
var constant1 = Expression.Constant(EntityUtility.ConvertToType(minVal, propertyInfo.PropertyType));
var constant2 = Expression.Constant(EntityUtility.ConvertToType(maxVal, propertyInfo.PropertyType));
if (Nullable.GetUnderlyingType(member.Type) != null)
{
member = Expression.Property(member, "Value");
}
var exMin = Expression.GreaterThanOrEqual(member, Expression.Convert(constant1, propertyInfo.PropertyType));
var exMax = Expression.LessThanOrEqual(member, Expression.Convert(constant2, propertyInfo.PropertyType));
operation = Expression.And(exMax, exMin);
执行查询后,它失败并抛出 message 错误Conversion failed when converting date and/or time from character string.
。它在 SQL 中转换为错误的日期时间格式。以下是日期时间输入值的转换 SQL 示例:
SELECT [user].[username]
FROM [dbo].[user] AS [user]
WHERE (CASE
WHEN [user].[update_date] <= '2018-03-24T00:00:01.0000000'
THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END & CASE
WHEN [user].[update_date] >= '2018-03-23T00:00:01.0000000'
THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END) = 1
go
问题在于格式2018-03-24T00:00:01.0000000
。这update_date
是 SQL Server 表中的日期时间列user
。
我该如何解决这个问题?非常感谢任何帮助。
更新:如果格式为2018-03-24T00:00:01.000
.
解决方案
首先,确保 EF Core 模型通过使用fluent API 或] 数据注释“知道”SqlServer 数据库表列类型是datetime
(默认情况下DateTime
属性映射到datetime2
类型) - 请参阅 EF Core 文档中的数据类型主题。HasColumnType
[Column
如果您需要为许多列进行设置,您可以使用类似于循环/反映所有 EF 模型中的所有属性的代码来设置 Column Type。
其次,参数化生成的 SQL 查询而不是使用常量值(文字)(几乎)总是更好。您可以通过将值包装在常量中并返回引用该属性Tuple
的表达式来做到这一点。Item1
像这样的东西:
static Expression ToExpression(object value)
{
if (value == null) return Expression.Constant(null);
var valueType = value.GetType();
var closureType = typeof(Tuple<>).MakeGenericType(valueType);
var closure = Activator.CreateInstance(closureType, value);
return Expression.Property(Expression.Constant(closure), "Item1");
}
Expression.Constant
并在您的代码中使用它而不是。执行此操作后,EF Core 将创建参数来代替当前文字。
旁注:如果您使用Expression.AndAlso
而不是Expression.And
. 前者表示逻辑 AND(C#&&
运算符),而后者是&
通常不在逻辑表达式中使用的按位 AND(C# 运算符)。同样适用于Expression.OrElse
vs Expression.Or
。
推荐阅读
- xaml - 将多个类的数据绑定到单个列表视图/xamarin 表单
- c++ - 编译器是否在由 new 初始化的对象上调用隐式析构函数
- javascript - 将 GTM 字符串格式的日期转换为 Javascript 中的日期对象
- security - Pay pal form post 提交时修改付款金额
- javascript - 使用 ajax、vanilla javascript 更新 Rails HTLM 表
- arrays - 减小 MATLAB 变量的文件大小
- printing - Xamarin Forms 需要帮助才能通过蓝牙打印机 XP200 进行打印
- .net - Wonderware 系统平台。如何从远程 PC 获取 DateTime?
- vba - 从 VBA 连接到 power bi 并导出大量数据
- c++ - 从“int”到“Vector*”的无效转换