首页 > 解决方案 > 如何使用 LINQ Query 对字符串执行日期范围过滤

问题描述

我正在尝试使用以下 linq 进行日期范围过滤:

IQueryable<Movies> movies= _context.Movies
            .OrderByDescending(i => i.Id).Select(i => i);

DateTime startDate = Convert.ToDateTime(searchStartDate);
DateTime endDate = Convert.ToDateTime(searchEndDate);

movies = movies.Where(i => Convert.ToDateTime(i.TransDate) >= startDate &&
                Convert.ToDateTime(i.TransDate) <= endDate)
                .OrderByDescending(j => j.Id);

但它不起作用,并且给了我 InvalidOperationException:无法翻译 LINQ 表达式“...”。

注意:我使用的数据库具有字符串格式的 TransDate 列('YYYY-MM-DD'),因此这个问题。

标签: c#linqasp.net-coreentity-framework-corerazor-pages

解决方案


虽然将日期作为字符串存储在数据库中并不是一个好主意,但至少所选格式是可订购的。虽然 EF Core 不提供将字符串转换为日期的可翻译方法,但它允许您拥有类型的实体属性DateTime(应该如此),并使用值转换器将其映射到数据库中的字符串列。因此,您将针对 编写查询DateTime,EF Core 会将常量/参数值转换为字符串并将它们传递给 SQL 查询。

将其应用于您的案例:

模型:

public class Movie
{
    // other properties...

    public DateTime TransDate { get; set; }
}

配置:

const string DateFormat = "yyyy-MM-dd";

modelBuilder.Entity<Movie>().Property(e => e.TransDate)
    .HasConversion(
        dateValue => dateValue.ToString(DateFormat, CultureInfo.InvariantCulture),
        stringValue => DateTime.ParseExact(stringValue, DateFormat, CultureInfo.InvariantCulture)
    )
    .IsRequired()
    .IsUnicode(false) // arbitrary
    .HasMaxLength(10); // arbitrary

LINQ 查询用法:

IQueryable<Movie> movies = ...;
DateTime startDate = ...;
DateTime endDate = ...;

movies = movies
    .Where(e => e.TransDate >= startDate && e.TransDate <= endDate);

推荐阅读