LINQ到SQL,带有日期类型字段的动态查询
我正在使用LINQ动态库构建一个查询,因此我不知道将有多少潜在参数,并且在尝试查询日期类型字段时出错: 运算符'>='与操作数类型“DateTime”和“String”不兼容。 当我在Dynamic.cs中单步执行调试器时,它显示值的类型为string,字段的类型为date,因此问题很明显,但我不知道如何处理它 有什么想法吗 溴 代码:LINQ到SQL,带有日期类型字段的动态查询,linq,linq-to-entities,Linq,Linq To Entities,我正在使用LINQ动态库构建一个查询,因此我不知道将有多少潜在参数,并且在尝试查询日期类型字段时出错: 运算符'>='与操作数类型“DateTime”和“String”不兼容。 当我在Dynamic.cs中单步执行调试器时,它显示值的类型为string,字段的类型为date,因此问题很明显,但我不知道如何处理它 有什么想法吗 溴 代码: 使用(MyEntities db=new MyEntities()) { 字符串SQLparam=“CreateDate>=\”“+DateTime.Now.T
使用(MyEntities db=new MyEntities())
{
字符串SQLparam=“CreateDate>=\”“+DateTime.Now.ToSortDateString()+“\”;
List UserList=db.UserList.Where(SQLparam.ToList();
}
您必须使用参数化查询,例如
using (MyEntities db = new MyEntities())
{
String SQLparam = "CreateDate >= @1";
List<UserList> UserList = db.UserList.Where(SQLparam, new [] { DateTime.Now }).ToList();
}
使用(MyEntities db=new MyEntities())
{
字符串SQLparam=“CreateDate>=@1”;
List UserList=db.UserList.Where(SQLparam,new[]{DateTime.Now}).ToList();
}
我也在同一条船上,我可以通过更改动态库中的一个方法来解决这个问题。这是一个黑客程序,但它允许我在表达式中使用带有相等运算符(=,>,)的日期,因为我必须对日期时间进行比较?我必须进行此修改
else if (left.Type == typeof(DateTime?) && right.Type == typeof(string))
{
if (right is ConstantExpression)
{
DateTime datevalue;
string value = ((ConstantExpression)right).Value.ToString();
if (DateTime.TryParse(value, out datevalue))
{
DateTime? nullableDateValue = datevalue;
right = Expression.Constant(nullableDateValue, typeof(DateTime?));
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
谢谢你的提示!我也遇到了同样的问题,但是布尔值也有问题,所以我推广了解决方案
Expression ConstantParser<T>(Expression left, Token op, Expression right, Func<string, T> parser)
{
if (right is ConstantExpression)
{
try
{
var value = ((ConstantExpression)right).Value.ToString();
return Expression.Constant(parser(value));
}
catch (Exception)
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
这种方法的唯一缺点是,如果解析失败,我们将引发异常,但考虑到我们无论如何都会抛出一个异常,我不认为这太重要了我认为我们需要了解一下您的代码在做什么-我认为如果没有大量假设和猜测,我们不足以回答问题。如果您不知道有多少,该怎么办会有潜在的参数吗?然后,您可以一边构建数组。这并不难。Mike,您是否曾经只需要与DateTime对象的日期部分进行比较?目前正在尝试与实体框架实体对象进行比较。您尝试过使用反射b修改动态Linq代码以使用myProperty.Value.date但恐怕不行。理想情况下,我希望它能创建一个lambda,比如p=>p.MyDateTimeProperty.Value.Date==“2012/08/01/而不是p=>p.MyDateTimeProperty==“2012/08/01”。对此有任何想法都将不胜感激。
// =, ==, !=, <>, >, >=, <, <= operators
Expression ParseComparison()
{
Expression left = ParseAdditive();
while (token.id == TokenId.Equal || token.id == TokenId.DoubleEqual ||
token.id == TokenId.ExclamationEqual || token.id == TokenId.LessGreater ||
token.id == TokenId.GreaterThan || token.id == TokenId.GreaterThanEqual ||
token.id == TokenId.LessThan || token.id == TokenId.LessThanEqual)
{
Token op = token;
NextToken();
Expression right = ParseAdditive();
bool isEquality = op.id == TokenId.Equal || op.id == TokenId.DoubleEqual ||
op.id == TokenId.ExclamationEqual || op.id == TokenId.LessGreater;
if (isEquality && !left.Type.IsValueType && !right.Type.IsValueType)
{
if (left.Type != right.Type)
{
if (left.Type.IsAssignableFrom(right.Type))
{
right = Expression.Convert(right, left.Type);
}
else if (right.Type.IsAssignableFrom(left.Type))
{
left = Expression.Convert(left, right.Type);
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
}
else if (IsEnumType(left.Type) || IsEnumType(right.Type))
{
if (left.Type != right.Type)
{
Expression e;
if ((e = PromoteExpression(right, left.Type, true)) != null)
{
right = e;
}
else if ((e = PromoteExpression(left, right.Type, true)) != null)
{
left = e;
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
}
else if (left.Type == typeof(DateTime) && right.Type == typeof(string))
{
if (right is ConstantExpression)
{
DateTime datevalue;
string value = ((ConstantExpression) right).Value.ToString();
if (DateTime.TryParse(value, out datevalue))
{
right = Expression.Constant(datevalue);
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
else
{
CheckAndPromoteOperands(isEquality ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures),
op.text, ref left, ref right, op.pos);
}
switch (op.id)
{
case TokenId.Equal:
case TokenId.DoubleEqual:
left = GenerateEqual(left, right);
break;
case TokenId.ExclamationEqual:
case TokenId.LessGreater:
left = GenerateNotEqual(left, right);
break;
case TokenId.GreaterThan:
left = GenerateGreaterThan(left, right);
break;
case TokenId.GreaterThanEqual:
left = GenerateGreaterThanEqual(left, right);
break;
case TokenId.LessThan:
left = GenerateLessThan(left, right);
break;
case TokenId.LessThanEqual:
left = GenerateLessThanEqual(left, right);
break;
}
}
return left;
}
else if (left.Type == typeof(DateTime?) && right.Type == typeof(string))
{
if (right is ConstantExpression)
{
DateTime datevalue;
string value = ((ConstantExpression)right).Value.ToString();
if (DateTime.TryParse(value, out datevalue))
{
DateTime? nullableDateValue = datevalue;
right = Expression.Constant(nullableDateValue, typeof(DateTime?));
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
Expression ConstantParser<T>(Expression left, Token op, Expression right, Func<string, T> parser)
{
if (right is ConstantExpression)
{
try
{
var value = ((ConstantExpression)right).Value.ToString();
return Expression.Constant(parser(value));
}
catch (Exception)
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
else if (left.Type == typeof(DateTime) && right.Type == typeof(string))
{
right = this.ConstantParser(left, op, right, DateTime.Parse);
}
else if (left.Type == typeof(DateTime?) && right.Type == typeof(string))
{
right = this.ConstantParser(left, op, right, x => { DateTime? t = DateTime.Parse(x); return t; });
}
else if (left.Type == typeof(Boolean) && right.Type == typeof(string))
{
right = this.ConstantParser(left, op, right, Boolean.Parse);
}