简体   繁体   English

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

[英]How to programmatically add JOINs to query from list using EF Core

I am trying to query data from database using EF Core, but the scenery is a bit complicated for me.我正在尝试使用 EF Core 从数据库中查询数据,但场景对我来说有点复杂。 I will try to be clear and synthesize what I want to accomplish.我会尽量清楚并综合我想要完成的事情。

There are three tables involved:涉及三个表:

  • Table WORK_TO_DO - Columns: ID, DESCRIPTION表 WORK_TO_DO - 列:ID、DESCRIPTION
  • Table PARAM_DEFINITIONS_FOR_WORK - Columns: ID, NAME表 PARAM_DEFINITIONS_FOR_WORK - 列:ID、NAME
  • Table PARAM_VALUES_FOR_WORK - Columns: WORK_TO_DO_ID, PARAM_DEFINITION_ID, VALUE表 PARAM_VALUES_FOR_WORK - 列:WORK_TO_DO_ID、PARAM_DEFINITION_ID、VALUE

Let's say these tables have their classes as below.假设这些表的类如下。

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; }
}

I have a list of ParamValue items with ParamDefinitionId and Value populated, but without WorkToDoId.我有一个 ParamValue 项目列表,其中填充了 ParamDefinitionId 和 Value,但没有 WorkToDoId。

I want to query all WorkToDo items that match the ParamValue items, considering all the ParamValue items and not just any of them.我想查询与 ParamValue 项目匹配的所有 WorkToDo 项目,同时考虑所有ParamValue 项目,而不仅仅是其中的任何项目。

Let me explain with example records on each table:让我用每个表上的示例记录来解释:

WORK_TO_DO要做的工作

ID ID DESCRIPTION描述
1 1个 Work Example A工作范例A
2 2个 Work Example B工作范例B

PARAM_DEFINITIONS_FOR_WORK PARAM_DEFINITIONS_FOR_WORK

ID ID NAME名称
101 101 Param Definition X参数定义 X
102 102 Param Definition Y参数定义 Y
103 103 Param Definition W参数定义 W
104 104 Param Definition Z参数定义 Z
105 105 Param Definition +参数定义 +

PARAM_VALUES_FOR_WORK PARAM_VALUES_FOR_WORK

WORK_TO_DO_ID WORK_TO_DO_ID PARAM_DEFINITION_ID PARAM_DEFINITION_ID VALUE价值
1 1个 101 101 Param Value J参数值 J
1 1个 102 102 Param Value K参数值 K
2 2个 103 103 Param Value L参数值 L
2 2个 104 104 Param Value M参数值 M
2 2个 105 105 Param Value N参数值 N

So, let's say my list of ParamValues has two items: ParamDefinitionId = 101, Value = "Param Value J" and ParamDefinitionId = 102, Value = "Param Value K" .因此,假设我的 ParamValues 列表有两项: ParamDefinitionId = 101, Value = "Param Value J"ParamDefinitionId = 102, Value = "Param Value K" I would like to retrieve the WorkToDo of Id = 1.我想检索 Id = 1 的 WorkToDo。

If my list of ParamValues had, instead, three items:如果我的 ParamValues 列表包含三个项目:

  • ParamDefinitionId = 103, Value = "Param Value L"
  • ParamDefinitionId = 104, Value = "Param Value M"
  • ParamDefinitionId = 105, Value = "Param Value N"

Then I would like my query to retrieve the WorkToDo of Id = 2.然后我希望我的查询检索 Id = 2 的 WorkToDo。

Note that the size of ParamValues list is variable!请注意,ParamValues 列表的大小是可变的!

I'd like to say that I have tried a solution, but the truth is I don't even know how to begin.我想说我已经尝试了一个解决方案,但事实是我什至不知道如何开始。 I've searched on the web but had no luck.我在 web 上搜索过,但没有成功。

I only have an idea of how I would do this using SQL:我只知道如何使用 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

Basically I want to add JOINs and filters to the query based on my list of ParamValues.基本上,我想根据我的 ParamValues 列表将 JOIN 和过滤器添加到查询中。 How can I do this?我怎样才能做到这一点?

Use FilterByItems extension and you can generate desired query:使用FilterByItems扩展,您可以生成所需的查询:

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
    );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM