我正在使用动态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字段之间进行比较而失败,这意味着查询已将我的日期文字解释为整数。
我应该如何格式化日期?
答案 0 :(得分:8)
使用
.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子句中的数字作为整数进行排序 - 这应该解释您最初得到的错误。
答案 1 :(得分:1)
为什么要解析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();
更新: 回应评论:我正在运行时构建那个。问题不是运行时与编译时;它是“在字符串中”与“在代码中”。 StringBuilder允许您追加文本; LINQ让链接lamdbas。这一切都是一样的 - 除了你的代码是类型安全的,并使用lambdas进行语法检查。
为了进一步说明这个概念,下面的代码编译和编译。运行正常,并允许您根据oddsOnly
和lowerLimit
的值更改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子句。
答案 2 :(得分:1)
Dynamic LINQ字符串需要看起来像:
"Date >= DateTime(2015, 10, 21)"
在http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library提到的下载中的DynamicQuery项目的文档中提到了这一点。
请注意,new
构造函数之前没有DateTime
。
我试过这个并且它有效。我正在使用Telerik的RadGrid控件来实现ASP.NET AJAX。网格构建过滤器字符串,我需要将过滤器添加到我的查询中,以使用LINQ to Entities在数据库中执行过滤器。问题是生成的过滤器需要稍微更改才能使用LINQ to Entities而不是LINQ to Objects。它正在执行DateTime.Parse()
,LINQ to Entities不支持。