Aca*_*hus 5 linq linq-to-entities
我正在使用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();
}
Run Code Online (Sandbox Code Playgroud)
您必须使用参数化查询,例如
using (MyEntities db = new MyEntities())
{
String SQLparam = "CreateDate >= @1";
List<UserList> UserList = db.UserList.Where(SQLparam, new [] { DateTime.Now }).ToList();
}
Run Code Online (Sandbox Code Playgroud)
我有同样的问题,但也有布尔,所以我推广了解决方案
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);
}
Run Code Online (Sandbox Code Playgroud)
主函数中的行然后变成......
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);
}
Run Code Online (Sandbox Code Playgroud)
我能看到这种方法的唯一缺点是,如果Parse失败,我们会提高和异常,但考虑到我们抛出一个,我不认为它太重要了
我在同一条船上,我能够通过更改动态库中的一个方法来解决这个问题.这是一个hack,但它允许我在具有相等运算符(=,>,<等等...)的表达式中使用日期.
我在这里发布代码以防有人仍在关心.
我添加的代码位于第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);
}
}
Run Code Online (Sandbox Code Playgroud)
代码基本上检查您是否尝试将日期字段(左)与字符串(右)进行比较.然后它将正确的表达式转换为日期常量
这是整个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;
}
Run Code Online (Sandbox Code Playgroud)
因为我不得不对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);
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢你的提示!
归档时间: |
|
查看次数: |
10427 次 |
最近记录: |