LINQ2SQL 表达式 - 转换日期时转换失败
LINQ2SQL Expression - Conversion failed when converting date
我有这个 Linq 表达式
var searchDate = DateTime.ParseExact("17.12.2018", "dd.MM.yyyy",
CultureInfo.InvariantCulture,
DateTimeStyles.None);
result = result.Where(DatePredicate("LaunchWeekStartDate", searchDate, 3));
我称这个表达式为
public static Expression<Func<General, bool>> DatePredicate(string columnName,
DateTime
searchValue,
int? operatorId)
{
var type = typeof(General);
var x = Expression.Parameter(type, "x");
var member = Expression.Property(x, columnName);
Expression expression;
var constant = Expression.Constant(searchValue, typeof(DateTime));
// Greater Than >
if (operatorId == 2)
{
expression = Expression.GreaterThan(member, constant); // THIS THROW ERROR
return Expression.Lambda<Func<General, bool>>(expression, x);
}
// Less Than <
else if (operatorId == 4)
{
expression = Expression.LessThan(member, constant); // THIS THROW ERROR
return Expression.Lambda<Func<General, bool>>(expression, x);
}
// Equal
var column = type.GetProperties().FirstOrDefault(p => p.Name == columnName);
expression = column == null
? expression = Expression.Constant(true) // THIS WORKS
: expression = Expression.Equal(member, constant); // THIS THROW ERROR
return Expression.Lambda<Func<General, bool>>(expression, x);
}
我得到的错误是
System.Data.SqlClient.SqlException (0x80131904): Conversion failed when converting date and/or time from character string.
这有效
var searchDate = DateTime.ParseExact("17.12.2018", "dd.MM.yyyy",
CultureInfo.InvariantCulture,
DateTimeStyles.None);
result = result.Where(x => x.LaunchWeekStartDate == searchDate);
LaunchWeekStartDate 的数据库列和 class 属性 是 DateTime 类型。
public class General
{
[Key]
public Int64 RowNumber {get; set;}
// ...
public DateTime LaunchWeekStartDate { get; set; }
}
拜托,你能解释一下这里的问题是什么吗?
编辑:
我尝试使用 Express.Call
和 CompareTo
方法,而不是 Express.Equal
。
var member = Expression.Property(x, columnName);
MethodInfo method = typeof(DateTime).GetMethod("CompareTo", new[] { typeof(DateTime) });
constant = Expression.Constant(searchValue, typeof(DateTime));
var call = Expression.Call(member, method, constant);
return Expression.Lambda<Func<General, bool>>(call, x);
但是我遇到了一个我不明白的异常:
System.ArgumentException: Expression of type 'System.Int32' cannot be used for return type 'System.Boolean'
这有效,我从这个 9 年前的博客中复制了它 https://www.tabsoverspaces.com/231060-comparing-date-only-in-ef
expression = Expression.And(
Expression.Equal(
Expression.MakeMemberAccess(member, typeof(DateTime).GetMember("Day").Single()),
Expression.Constant(searchValue.Day)
),
Expression.And(
Expression.Equal(
Expression.MakeMemberAccess(member, typeof(DateTime).GetMember("Month").Single()),
Expression.Constant(searchValue.Month)
),
Expression.Equal(
Expression.MakeMemberAccess(member, typeof(DateTime).GetMember("Year").Single()),
Expression.Constant(searchValue.Year)
)
)
);
但在我看来,这样的任务有点复杂。
我也不知道如何用这种方法制作 GreaterThan
和 LessThen
:/
编辑: 现在它也适用于大于和小于
// Greater Than >
expression = Expression.GreaterThan(Expression.MakeMemberAccess(member, typeof(DateTime).GetMember("Date").Single()), constant);
// Less Than <
expression = Expression.LessThan(Expression.MakeMemberAccess(member, typeof(DateTime).GetMember("Date").Single()), constant);
// Equal
expression = Expression.Equal(Expression.MakeMemberAccess(member, typeof(DateTime).GetMember("Date").Single()), constant);
查看我对此的回答 post here
解决方案是如何使 EntityFramework 生成带参数的 SqlCommand,以便数据类型映射可以将 CLR DateTime 转换为 SQL 服务器等效项。
我有这个 Linq 表达式
var searchDate = DateTime.ParseExact("17.12.2018", "dd.MM.yyyy",
CultureInfo.InvariantCulture,
DateTimeStyles.None);
result = result.Where(DatePredicate("LaunchWeekStartDate", searchDate, 3));
我称这个表达式为
public static Expression<Func<General, bool>> DatePredicate(string columnName,
DateTime
searchValue,
int? operatorId)
{
var type = typeof(General);
var x = Expression.Parameter(type, "x");
var member = Expression.Property(x, columnName);
Expression expression;
var constant = Expression.Constant(searchValue, typeof(DateTime));
// Greater Than >
if (operatorId == 2)
{
expression = Expression.GreaterThan(member, constant); // THIS THROW ERROR
return Expression.Lambda<Func<General, bool>>(expression, x);
}
// Less Than <
else if (operatorId == 4)
{
expression = Expression.LessThan(member, constant); // THIS THROW ERROR
return Expression.Lambda<Func<General, bool>>(expression, x);
}
// Equal
var column = type.GetProperties().FirstOrDefault(p => p.Name == columnName);
expression = column == null
? expression = Expression.Constant(true) // THIS WORKS
: expression = Expression.Equal(member, constant); // THIS THROW ERROR
return Expression.Lambda<Func<General, bool>>(expression, x);
}
我得到的错误是
System.Data.SqlClient.SqlException (0x80131904): Conversion failed when converting date and/or time from character string.
这有效
var searchDate = DateTime.ParseExact("17.12.2018", "dd.MM.yyyy",
CultureInfo.InvariantCulture,
DateTimeStyles.None);
result = result.Where(x => x.LaunchWeekStartDate == searchDate);
LaunchWeekStartDate 的数据库列和 class 属性 是 DateTime 类型。
public class General
{
[Key]
public Int64 RowNumber {get; set;}
// ...
public DateTime LaunchWeekStartDate { get; set; }
}
拜托,你能解释一下这里的问题是什么吗?
编辑:
我尝试使用 Express.Call
和 CompareTo
方法,而不是 Express.Equal
。
var member = Expression.Property(x, columnName);
MethodInfo method = typeof(DateTime).GetMethod("CompareTo", new[] { typeof(DateTime) });
constant = Expression.Constant(searchValue, typeof(DateTime));
var call = Expression.Call(member, method, constant);
return Expression.Lambda<Func<General, bool>>(call, x);
但是我遇到了一个我不明白的异常:
System.ArgumentException: Expression of type 'System.Int32' cannot be used for return type 'System.Boolean'
这有效,我从这个 9 年前的博客中复制了它 https://www.tabsoverspaces.com/231060-comparing-date-only-in-ef
expression = Expression.And(
Expression.Equal(
Expression.MakeMemberAccess(member, typeof(DateTime).GetMember("Day").Single()),
Expression.Constant(searchValue.Day)
),
Expression.And(
Expression.Equal(
Expression.MakeMemberAccess(member, typeof(DateTime).GetMember("Month").Single()),
Expression.Constant(searchValue.Month)
),
Expression.Equal(
Expression.MakeMemberAccess(member, typeof(DateTime).GetMember("Year").Single()),
Expression.Constant(searchValue.Year)
)
)
);
但在我看来,这样的任务有点复杂。
我也不知道如何用这种方法制作 GreaterThan
和 LessThen
:/
编辑: 现在它也适用于大于和小于
// Greater Than >
expression = Expression.GreaterThan(Expression.MakeMemberAccess(member, typeof(DateTime).GetMember("Date").Single()), constant);
// Less Than <
expression = Expression.LessThan(Expression.MakeMemberAccess(member, typeof(DateTime).GetMember("Date").Single()), constant);
// Equal
expression = Expression.Equal(Expression.MakeMemberAccess(member, typeof(DateTime).GetMember("Date").Single()), constant);
查看我对此的回答 post here
解决方案是如何使 EntityFramework 生成带参数的 SqlCommand,以便数据类型映射可以将 CLR DateTime 转换为 SQL 服务器等效项。