首页 > 解决方案 > Linq过滤部分日期

问题描述

我有一个输入和一个数据表,当用户输入该输入时,我根据用户输入的内容过滤 KeyUp 上的数据。就像 datatables.net 一样,但它是从头开始学习的。

数据表有 3 列全名(字符串)、城市(字符串)和出生日期(日期时间)。

我想如果用户键入例如:“2/”,它将给他所有包含 2/ 的 DOB。到目前为止,这是我的代码(我尝试了很多但没有成功)。

    var data = _context.Person.Where(p => p.DateOfBirth.Value
                       .ToString("d").Split()[0].Contains(SearchQuery)).ToList();

// Split() 删除时间部分。

和:

var data = _context.Person.Where(p => p.DateOfBirth.Value
                           .ToString().Contains(SearchQuery)).ToList();

但两者都给了我一个例外:“方法 System.DateTime.ToString 的翻译”失败

标签: c#entity-frameworklinq

解决方案


当您使用 LINQ-to-entities 时,您的 C# 代码实际上并没有被执行。它被解析。运行时会将 C# 代码解析为表达式,并将每个符号转换为 SQL 字符串的某些部分。然后它将这个字符串发送到数据库以在服务器上执行。服务器不支持同种日期格式,所以不支持你的方法调用表达式;无法将其转换为 SQL 字符串。

但是,这里更大的问题是您不应该每次击键都敲击数据库;这将导致问题。

相反,当您加载表单时,只需访问数据库一次。将列表缓存在内存中。你可以通过调用来做到这一点ToList。将结果存储在成员变量中。

List<Person> _data;

void Form_Load(object sender, EventArgs e)
{
    _data = _context.Person.ToList();
}

现在您有了一个本地副本,您可以使用它而不是调用数据库。而且由于您的 LINQ 查询不必转换为 SQL 语句,因此您可以使用任何您想要的 c# 方法。

void SearchQuery_KeyUp(object sender, KeyEventArgs e)
{
     var data = _data.Where(p => p.DateOfBirth.Value
                   .ToString("d").Split()[0].Contains(SearchQuery)).ToList();
     Display(data);
}

推荐阅读