如何使用 EF Core 以编程方式添加 JOIN 以从列表中查询

How to programmatically add JOINs to query from list using EF Core

我正在尝试使用 EF Core 从数据库中查询数据,但场景对我来说有点复杂。我会尽量清楚并综合我想要完成的事情。

涉及三个table:

假设这些 table 的 类 如下所示。

public class WorkToDo
{
    public int Id { get; set; }
    public string Description { get; set; }
}

public class ParamDefinition
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class ParamValue
{
    public int WorkToDoId { get; set; }
    public int ParamDefinitionId { get; set; }
    public string Value { get; set; }
}

我有一个 ParamValue 项目列表,其中填充了 ParamDefinitionId 和 Value,但没有 WorkToDoId。

我想查询与 ParamValue 项目匹配的所有 WorkToDo 项目,考虑 所有 ParamValue 项目,而不仅仅是其中的任何项目。

让我用示例记录来解释每个 table:

WORK_TO_DO

ID DESCRIPTION
1 Work Example A
2 Work Example B

PARAM_DEFINITIONS_FOR_WORK

ID NAME
101 Param Definition X
102 Param Definition Y
103 Param Definition W
104 Param Definition Z
105 Param Definition +

PARAM_VALUES_FOR_WORK

WORK_TO_DO_ID PARAM_DEFINITION_ID VALUE
1 101 Param Value J
1 102 Param Value K
2 103 Param Value L
2 104 Param Value M
2 105 Param Value N

那么,假设我的 ParamValues 列表有两项:ParamDefinitionId = 101, Value = "Param Value J"ParamDefinitionId = 102, Value = "Param Value K"。我想检索 Id = 1 的 WorkToDo。

如果我的 ParamValues 列表包含三个项目:

然后我希望我的查询检索 Id = 2 的 WorkToDo。

请注意,ParamValues 列表的大小是可变的!

我想说我已经尝试了一个解决方案,但事实是我什至不知道如何开始。我在网上搜索过,但没有找到。

我只知道如何使用 SQL:

SELECT DISTINCT WORK_TO_DO.ID, WORK_TO_DO.DESCRIPTION
FROM WORK_TO_DO
INNER JOIN PARAM_VALUES_FOR_WORK PV1 ON PV1.WORK_TO_DO_ID = WORK_TO_DO.ID
INNER JOIN PARAM_VALUES_FOR_WORK PV2 ON PV2.WORK_TO_DO_ID = WORK_TO_DO.ID
(... Adding as many INNER JOINs as needed based on list of ParamValues)
INNER JOIN PARAM_VALUES_FOR_WORK PVX ON PVX.WORK_TO_DO_ID = WORK_TO_DO.ID
WHERE PV1.PARAM_DEFINITION_ID = :ParamValues[0].ParamDefinitionId
  AND PV1.VALUE = :ParamValues[0].Value
  AND PV2.PARAM_DEFINITION_ID = :ParamValues[1].ParamDefinitionId
  AND PV2.VALUE = :ParamValues[1].Value
  (... Adding as many conditions as needed based on list of ParamValues)
  AND PVX.PARAM_DEFINITION_ID = :ParamValues[X].ParamDefinitionId
  AND PVX.VALUE = :ParamValues[X].Value

基本上,我想根据我的 ParamValues 列表将 JOIN 和过滤器添加到查询中。我该怎么做?

使用 扩展,您可以生成所需的查询:

var requiredCount = ParamValues.Count();

var query = context.WorkToDo
    .Where(w => context.ParamValue
        .Where(pv = pv.WorkToDoId == w.Id)
        .FilterByItems(ParamValues, (pv, v) => pv.ParamDefinitionId == v.ParamDefinitionId && pv.Value == v.Name, true)
        .Count() >= requiredCount
    );