【问题标题】:How do I format date literals in dynamic linq?如何在动态 linq 中格式化日期文字?
【发布时间】:2015-10-22 10:00:08
【问题描述】:

我正在使用动态 Linq 返回用户输入搜索条件的数据。除了用户选择的日期外,我的查询工作正常。我当前的代码是:

        StringBuilder whereClause = new StringBuilder();

        if (startDate.HasValue || endDate.HasValue)
        {
            DateTime searchStartDate = startDate.HasValue ? startDate.Value : DateTime.MinValue;
            DateTime searchEndDate = endDate.HasValue ? endDate.Value : DateTime.MaxValue;

            whereClause.AppendFormat("Date >= {0} && Date <= {1}",
                searchStartDate.Date.ToUniversalTime(),
                searchEndDate.Date.ToUniversalTime());
        }

        if (whereClause.Length > 0)
        {
            return (from p in this.repository.GetQueryable<Party>() select p)
                .Where(whereClause.ToString())
                .ToList();
        }

查询失败,因为在 DateTime 字段和 Int32 字段之间进行比较,这意味着查询已将我的日期文字解释为整数。

我应该如何格式化日期?

【问题讨论】:

    标签: c# linq datetime dynamic


    【解决方案1】:

    使用

    .Where("Date >= @0 && Date <= @1",
                    searchStartDate.Date.ToUniversalTime(),
                    searchEndDate.Date.ToUniversalTime())
    

    改为。

    回复 Val 的评论:

    好的,那么你可以这样做:

    whereClause.AppendFormat("Date.ToString() >= \"{0}\" && Date.ToString() <= \"{1}\"",
                    searchStartDate.Date.ToUniversalTime(),
                    searchEndDate.Date.ToUniversalTime());
    

    您必须将查询中的日期转换为字符串,然后将其与带引号的字符串文字进行比较。如果没有引号,解析器会将插入 where 子句的数字解释为整数 - 应该解释您最初遇到的错误。

    【讨论】:

    • Obalix,我真的需要将整个 .Where 子句作为字符串,因为我正在附加其他搜索词,因此该子句的日期元素可能不存在。
    【解决方案2】:

    为什么要在 LINQ 表达式中解析字符串? LINQ 的全部意义在于避免这种情况。

    var q =  from p in this.repository.GetQueryable<Party>() select p;
    
    if (startDate.HasValue || endDate.HasValue) 
    { 
      var searchStartDate = startDate.HasValue ? startDate.Value : DateTime.MinValue; 
      var searchEndDate = endDate.HasValue ? endDate.Value : DateTime.MaxValue; 
      return 
             q.Where (p=> p.Date >= searchStartDate.ToUniversalTime() 
                       && p.Date <= searchEndDate.ToUniversalTime()).ToList();
    } 
    return q.ToList();
    

    更新: 作为对 cme​​ts 的回应:我正在运行时构建那个。问题不是运行时与编译时;它是“在字符串中”与“在代码中”。 StringBuilder 允许您附加文本; LINQ 允许链接 lamdbas。一切都一样——除了你的代码是类型安全的并且使用 lambdas 检查语法。

    为了进一步演示这个概念,下面的代码编译和运行良好,并允许您根据 oddsOnlylowerLimit 的值更改 Where 子句。

    int[] nums = {1,2,3,4,5,6,7,8,9,10};
    
    bool oddsOnly = true; 
    bool lowerLimit = 5;
    
    var q = from i in nums select i;
    
    if (oddsOnly)
        q = q.Where( n=> n%2 == 1);
    
    if (lowerLimit != 0)
        q = q.Where( n=> n >= lowerLimit);
    
    foreach(var i in q)
        Console.WriteLine(i);
    

    根据您设置这些值的方式,它将使用零个、一个或两个 where 子句。

    【讨论】:

    • 正常情况下,这个说法是可以的。但是在某些情况下,例如根据用户输入动态生成过滤器,Dynamic Linq 是一个有效的替代方案。
    • James,我需要在运行时构建查询,因为用户可以输入任何搜索词,也可以不输入任何搜索词。我在我的代码 sn-p 中省略了其他术语,但是我正在构建的 .Where 字符串只能在运行时完成。
    • 问题是我的 .Where 子句中没有或没有任何数量的术语,具体取决于用户输入的内容。我省略了非日期的 sn-ps,但对于每条用户输入,我检查空值并仅在需要时将相关术语附加到 whereClause 字符串。我的 whereClause 最后可能是空的。我不想在“if not null...”部分中执行搜索,因为我最终会得到多个“if...else”分支,具体取决于所使用的搜索词。难道没有办法将整个子句构建为一个字符串,然后在最后执行它吗?
    • 问题是关于“动态 linq”
    • @MVision- 问题是关于取得成果。
    【解决方案3】:

    动态 LINQ 字符串需要如下所示:

    "Date >= DateTime(2015, 10, 21)"
    

    http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library 提到的下载中 DynamicQuery 项目的文档中提到了这一点。

    注意,DateTime 构造函数之前没有new

    我试过了,效果很好。我正在为 ASP.NET AJAX 使用 Telerik 的 RadGrid 控件。网格构建过滤器字符串,我需要将过滤器添加到我的查询中,以使用 LINQ to Entities 在数据库中执行过滤器。问题是生成的过滤器需要稍作修改才能与 LINQ to Entities 一起使用,而不是 LINQ to Objects。它正在执行DateTime.Parse(),LINQ to Entities 不支持。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多