Linq过滤部分日期



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

数据表有3列fullname(字符串(、city(字符串(和dateofbirth(日期时间(。

如果用户键入例如:";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的翻译"失败

当您对实体使用LINQ时,您的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);
}

您可以使用LIKE语句,它将接近于实现您想要的目标。

var data = _context.Person.Where(p => EF.Functions.Like(p.DateOfBirth, $"%{searchquery}%")).ToList();

问题是,如果将日期保存为DateTimeDateTime2DateTimeOffset字段,则它们在数据库中的表示形式将与您输入的字符串表示形式不同。也就是说,它们可能没有"/"(尽管由于您没有提到您的数据库技术,因此无法确定(。

如果您首先通过调用例如context.person.ToList()将表加载到内存,那么您的方法应该可以工作,并且不应该失败地将DateTime转换为string

我建议如下:

_context.Person.ToList().Where(p => p.DateOfBirth.Value
.ToString("dd/MM/yyyy").Contains(SearchQuery)).ToList();

最新更新