EF中使用Lambda表达式的多个where条件

本文关键字:where 条件 表达式 Lambda EF | 更新日期: 2023-09-27 18:16:00

我正在使用实体框架和Linq Querable,我想使用多个where子句选择一些数据。

在我的数据库中,我在一个字段中可能有多个id FieldOfInterestID,用";"分隔(I know, I know, but it's late to do something),或者只有一个id,这意味着逗号不会出现

我想用";"分隔符分割字符串,然后在我的where子句中使用所有这些id。

我的代码看起来像这样:

await ctx.Customer.AsNoTracking()
    .Where(e => e.UserId == userId)
    .Select(e => new UserDTO {
        FieldsOfStudy = ctx.Terms.Where(t => {
            if (!e.FieldOfInterestID.Contains(";") && t.TermId.ToString() == e.FieldOfInterestID)
                return true;
            else if (e.FieldOfInterestID.Contains(";")
            {
                string fieldOfInterestIds = e.FieldOfInterestID.Split(";");
                foreach (string fieldOfInterestID in fieldOfInterestIds)
                {
                    if (t.TermId.ToString() == e.FieldOfInterestID)
                        return true;
                    else
                        return false;
                }
            }
            else
                return false;
        }
    })
    .ToListAsync().ConfigureAwait(false);

我当前的"错误"是not all code paths return a value...

如何在where子句中更好地使用string[] ?

EF中使用Lambda表达式的多个where条件

当前的错误是由于这个分支:

foreach (string fieldOfInterestID in fieldOfInterestIds)
{
    if (t.TermId.ToString() == e.FieldOfInterestID)
        return true;
    else
        return false;
}

从编译器的角度来看,foreach的主体可以不输入,因此not all code paths return a value...

你可以通过将return false;移出body来修复它:

foreach (string fieldOfInterestID in fieldOfInterestIds)
{
    if (t.TermId.ToString() == e.FieldOfInterestID)
        return true;
}
return false;

这将修复编译器错误,但不能解决问题。一旦你运行它,你会发现LINQ to Entities不支持带body (=> { ... })和string.Split方法的lambda表达式。

真正的解决方案需要不同的标准——而不是不支持的

e.FieldOfInterestID.Split(";").Contains(t.TermId.ToString())

相反,但支持(使用字符串连接和string.Contains)

(";" + e.FieldOfInterestID + ";").Contains(";" + t.TermId + ";")

需要用;包围两个字符串,以正确处理第一个、中间和最后一个标记。

最后的查询可以像这样:

var query = ctx.Customer.AsNoTracking()
    .Where(e => e.UserId == userId)
    .Select(e => new UserDTO
    {
        FieldsOfStudy = ctx.Terms
            .Where(t => (";" + e.FieldOfInterestID + ";").Contains(";" + t.TermId + ";"))
    });

我觉得这行不对:

string fieldOfInterestIds = e.FieldOfInterestID.Split(";");

我会把它改成:

string[] fieldOfInterestIds = e.FieldOfInterestID.Split(";");

我还想简化一下代码:

ctx.Terms.Where(t => return e.FieldOfInterestID.Split(";").Contains(t.TermId.ToString()));

如果字符串不包含;字符,它返回一个包含一个项目的字符串[]