【问题标题】:Multiple where conditions in EF using Lambda expressions使用 Lambda 表达式的 EF 中的多个 where 条件
【发布时间】:2016-11-02 11:52:24
【问题描述】:

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

在我的数据库中,我在一个字段中可能有多个 ID FieldOfInterestID,用“;”分隔(我知道,我知道,但做某事为时已晚),或者只有一个 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[]?

【问题讨论】:

  • 您的 foreach() 将运行 0 或 1 次。那是你的本意吗? 0 次情况是导致此错误的原因,但是您真正希望 2 个或更多元素发生什么?
  • @HenkHolterman,不,我不是故意的 :)
  • 你需要a rubber duck

标签: c# .net entity-framework linq lambda


【解决方案1】:

当前的错误是因为这个分支:

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; 移到体外来修复它:

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

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

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

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 + ";"))
    });

【讨论】:

    【解决方案2】:

    这行对我来说似乎是错误的:

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

    我会改成:

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

    我还要稍微简化一下代码:

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

    如果字符串不包含;characters,则返回一个字符串[],其中包含一项

    【讨论】:

    • 有效的 remakrks 但与“并非所有代码路径都返回值”无关
    • 如果我使用 .contains ,我想我不再需要拆分了,对吧?
    • @SGN '我想我不再需要拆分' 这取决于 TermId 值。 "135".Contains("3") 将返回 true。类似于 String.IndexOf "135;12".Split(";").Contains("3") 将返回 false "135;12".Split(";").Contains("12") 将返回 true
    猜你喜欢
    • 2017-07-22
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    相关资源
    最近更新 更多