我正在使用LINQ动态库构建查询,因此我不知道有多少潜在参数,并且在尝试查询DATE类型字段时出现错误:
运算符'> ='与操作数类型'DateTime'和'String'不兼容
当我单步执行Dynamic.cs中的调试器时,它显示该值的类型为字符串,并且该字段的类型为date,因此问题很明显,但我不知道如何处理它。
有什么想法吗?
BR
代码:
using (MyEntities db = new MyEntities())
{
String SQLparam = "CreateDate >= \"" + DateTime.Now.ToShortDateString() + "\"";
List<UserList> UserList = db.UserList.Where(SQLparam).ToList();
}
答案 0 :(得分:9)
您必须使用参数化查询,例如
using (MyEntities db = new MyEntities())
{
String SQLparam = "CreateDate >= @1";
List<UserList> UserList = db.UserList.Where(SQLparam, new [] { DateTime.Now }).ToList();
}
答案 1 :(得分:9)
我遇到了同样的问题,但是布尔也是如此,所以我推广了解决方案
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);
}
我唯一可以看到这种方法的缺点是,如果Parse失败,我们会提高和异常,但考虑到我们抛出一个,我不认为它太重要
答案 2 :(得分:8)
我在同一条船上,我能够通过更改动态库中的一个方法来解决这个问题。这是一个hack,但它允许我在具有相等运算符的表达式中使用日期(=,&gt;,&lt;,etc ..)。
我在这里发布代码以防有人仍在关心。
我添加的代码位于第53行的if块
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);
}
}
代码基本上检查您是否尝试将日期字段(左)与字符串(右)进行比较。然后它将正确的表达式转换为日期常量
以下是整个ParseComparison方法:
// =, ==, !=, <>, >, >=, <, <= 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;
}
答案 3 :(得分:5)
因为我必须对DateTime进行比较?我做了这个修改。
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);
}
}
感谢您的提示!