如何使用 EF Core 以编程方式添加 JOIN 以从列表中查询
How to programmatically add JOINs to query from list using EF Core
我正在尝试使用 EF Core 从数据库中查询数据,但场景对我来说有点复杂。我会尽量清楚并综合我想要完成的事情。
涉及三个table:
- Table WORK_TO_DO - 列:ID、描述
- Table PARAM_DEFINITIONS_FOR_WORK - 列:ID、NAME
- Table PARAM_VALUES_FOR_WORK - 列:WORK_TO_DO_ID、PARAM_DEFINITION_ID、VALUE
假设这些 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 列表包含三个项目:
ParamDefinitionId = 103, Value = "Param Value L"
ParamDefinitionId = 104, Value = "Param Value M"
ParamDefinitionId = 105, Value = "Param Value N"
然后我希望我的查询检索 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
);
我正在尝试使用 EF Core 从数据库中查询数据,但场景对我来说有点复杂。我会尽量清楚并综合我想要完成的事情。
涉及三个table:
- Table WORK_TO_DO - 列:ID、描述
- Table PARAM_DEFINITIONS_FOR_WORK - 列:ID、NAME
- Table PARAM_VALUES_FOR_WORK - 列:WORK_TO_DO_ID、PARAM_DEFINITION_ID、VALUE
假设这些 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 列表包含三个项目:
ParamDefinitionId = 103, Value = "Param Value L"
ParamDefinitionId = 104, Value = "Param Value M"
ParamDefinitionId = 105, Value = "Param Value N"
然后我希望我的查询检索 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
);