LINQ到SQL,带有日期类型字段的动态查询

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

我正在使用LINQ动态库构建一个查询,因此我不知道将有多少潜在参数,并且在尝试查询日期类型字段时出错:

运算符'>='与操作数类型“DateTime”和“String”不兼容。

当我在Dynamic.cs中单步执行调试器时,它显示值的类型为string,字段的类型为date,因此问题很明显,但我不知道如何处理它

有什么想法吗

代码:

使用(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);
}