c# - 如何使用 Entity Framework 在具有多个联接的查询中使用可选参数?

标签 c# entity-framework-core optional-parameters

我已经研究了该问题的几种可能的解决方案,但我尝试过的解决方案似乎不起作用。一种解决方案是对可选过滤器使用 if 语句,但这不起作用,因为我有多个联接,并且 where 子句位于最后一个联接中。

可选参数为:roleId、disciplineId、resourceId 和 projectName。

try
{
    IQueryable<ProjectPlanHeader> bob = 
        (
            from h in context.ProjectPlanHeaders
            join r in context.ProjectPlanRevisions on h.ProjectPlanHeaderId equals r.ProjectPlanHeaderId
            join a in context.PlanActivityLineItems on r.PlanRevisionId equals a.PlanRevisionId
            where ((roleId == null || a.RequiredRoleId == roleId) && 
                (disciplineId == null || a.DisciplineId == disciplineId) && 
                (resourceId == null || a.ActualResourceId == resourceId) && 
                (h.ProjectPlanName.ToLower().Contains(projectName.ToLower()) || projectName == String.Empty))
            select h
        )
        .Include(x => x.ProjectPlanRevisions)
            .ThenInclude(y => y.PlanActivityLineItem)
                .ThenInclude(z => z.PlannedHours)
        .Include(x => x.ActualPlanRevisions)
            .ThenInclude(y => y.ActualPlanActivities)
                .ThenInclude(z => z.ActualHours);

    var john = bob.ToList();
    return bob;
}
catch (Exception ex)
{
    return null;
}

我添加了 try/catch,这样我就可以看到发生了什么,因为它默默地失败了。我发现的是“对象未设置为对象的实例”。这从来没有帮助,因为我不知道它在谈论什么对象。有人可以告诉我如何正确地做到这一点吗?

更新:感谢您收到的回复,但不幸的是它们不起作用。问题是当我过滤时我最终得到多个 header 。发生这种情况是因为每个标题都有多个修订版,而我实际上只需要最大修订版。我尝试更改初始查询,以便仅包含最大转速,但这仍然没有帮助。这个问题似乎没有解决方案,所以我必须采取另一种方式。

最佳答案

重写查询以不使用显式联接,因为您具有导航属性。另外,由于 JOINS 你有重复的记录,你稍后会发现它。

var query = context.ProjectPlanHeaders
    .Include(x => x.ProjectPlanRevisions)
        .ThenInclude(y => y.PlanActivityLineItem)
            .ThenInclude(z => z.PlannedHours)
    .Include(x => x.ActualPlanRevisions)
        .ThenInclude(y => y.ActualPlanActivities)
            .ThenInclude(z => z.ActualHours)
    .AsQueryable();

if (!string.IsNullOrEmpty(projectName))
{
    // here we can combine query
    query = query
        .Where(h => h.ProjectPlanName.ToLower().Contains(projectName.ToLower()));
}

// check that we have to apply filter on collection
if (roleId != null || disciplineId != null || resourceId != null)
{
    // here we have to do filtering as in original query
    query = query
        .Where(h => h.ProjectPlanRevisions
            .Where(r => roleId == null || r.PlanActivityLineItem.RequiredRoleId == roleId)
            .Where(r => disciplineId == null || r.PlanActivityLineItem.DisciplineId == disciplineId)
            .Where(r => resourceId == null || r.PlanActivityLineItem.ActualResourceId == resourceId)
            .Any()
        );
}

var result = query.ToList();

关于c# - 如何使用 Entity Framework 在具有多个联接的查询中使用可选参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73243034/

相关文章:

c# - 检查后代是否匹配 C#

asp.net-core - .NET Core 1.0 和 EntityFramework 7 不兼容

c# - 无法通过一个查询使用 Include 或 ThenInclude 或 Select/Many 加载相关数据

reflection - 带有可选参数的 Activator.CreateInstance

c# - 如何使用 xamarin.forms 在弹出窗口中创建表单?

c# - 文件流没有完成写入文件

c# - System.Security.Principal.WindowsIdentity 的这种使用是否合理安全?

linq - EF.Functions.Contains 包括多个关键字

java - 在 Java 中传递的可选匿名参数

带有可选参数的 C++ 构造函数