使用Linq查询按日期搜索

时间:2015-09-23 06:11:03

标签: c# json asp.net-mvc linq datetime

我有数据库表,它有一个字段调用 CreatedDate ,它是DateTime格式。

例如:在该字段中,值保存为2015-08-27 13:28:50.333NULL

我写了以下Linq查询,以typecategorycountrysubsidary和日期进行搜索。 typecategorycountrysubsidary字段为nvarchar字段,日期为DateTime字段

    [HttpGet]
    public JsonResult FetchProducts(string type, string category, string country, string subsidary, string dateHERE)
    {

        DateTime? mydate = null;
        DateTime date2;
        bool check = DateTime.TryParse(dateHERE, out date2);
        if (check)
        {
            mydate = date2;
        }

        ................


        if (!string.IsNullOrWhiteSpace(type))
            products = products.Where(p => p.ProductType_ID.StartsWith(type));

        ....................

        if (check)
        {
           products = products.Where(p => p.CreatedDate.Equals(mydate)).ToList();
        }

        ...............

        return Json(data, JsonRequestBehavior.AllowGet);
    }

一旦我输入日期并搜索我就变为空

此查询适用于除date以外的几乎所有字段。是什么修正linq查询来搜索日期。

5 个答案:

答案 0 :(得分:1)

你必须截断时间:

 ...products.Where(p => EntityFunctions.TruncateTime(p.CreatedDate) == mydate)

如果您使用的是EF6,请将EntityFunctions更改为DbFunctions

其他信息:

EntityFunctions方法称为 规范函数 。这些是一组功能,所有实体框架提供程序都支持这些功能。这些规范函数将转换为提供程序的相应数据源功能。规范函数是访问核心语言之外的功能的首选方法,因为它们可以使查询保持可移植性。

您可以找到所有规范函数here以及所有日期和时间规范函数here

不要忘记添加对System.Data.ObjectsSystem.Data.Entity的引用。

另外您可以使用该逻辑截断时间部分:

DateTime? myDateTomorrow = myDate;
myDateTomorrow.Value.AddDays(1);

products.Where(p => p.CreatedDate >= mydate && p.CreatedDate < myDateTomorrow);

答案 1 :(得分:1)

如果您的查询来自SQL后端,您始终必须记住数据库引擎应该能够将生成的SQL转换为有效的执行计划。因此,要考虑的一个重要因素是索引使用情况。如果在谓词中使用数据库字段之前对其进行转换,则该字段上的任何索引都将被禁用:

WHERE dateField = date -- index on dateField can be used

VS

WHERE DATEPART(.. dateField ..) = date -- index can't be used

所以做范围检查可能更好:

...
mydate = date2.Date;
...


if (mydate.HasValue)
{
   var mydatePlus = mydate.Value.AddDays(1);
   products = products.Where(p => p.CreatedDate >= mydate && p.CreatedDate < mydatePlus)
                      .ToList();
}

这也称为 sargable 表达式。

答案 2 :(得分:0)

由于这里的每个人都已经提到你的日期.Equals()因为毫秒而无法工作我通常使用Date类的DateTime属性,它只获取数据时间对象的日期部分所以我建议你这样做:

if (check)
{
    products = products.Where(p => p.CreatedDate != null //check on null
    && p.CreatedDate.Value.Date == mydate).ToList();
}

答案 3 :(得分:0)

其他更灵活的方式......

Expression<Func<Products, bool>> expresionFinal = p => p.Active;

if (mydate.HasValue)
{
    Expression<Func<Products, bool>> expresionDate = p => (EntityFunctions.TruncateTime(c.CreatedDate) <= mydate);
    expresionFinal = PredicateBuilder.And(expresionFinal, expresionDate );
}

IQueryable<T> query = dbSet;


    query = query.Where(expresionFinal);

答案 4 :(得分:0)

我使用此linq查询在日期列中进行搜索:

var list = db.records;
DateTime? date_start;

if (date_start != null)
{
   list = list.Where(x => x.date != null &&
   x.date.Value.Date >= date_start.Value.Date);
}

这将返回日期> = date_start的所有记录