【发布时间】:2019-09-13 23:29:14
【问题描述】:
当我的 PARENTS 表中所有已完成的父项在某个日期范围内完成时,我需要返回它们。针对父级的所有操作都存储在子表 PARENT_ACTIONS 中。我遇到的困难是,完成操作后可能还有更多操作,甚至为该 PARENT_ID 存储了多个已完成操作,我只需要返回父级,如果最大操作是已完成的操作,它在用户选择的日期范围内。
我尝试过搜索论坛,但我发现的大部分内容都是“如何找到父记录的子记录的最大日期”,这对如何做最大值很有帮助,但对我的确切的问题。
我不记得我尝试过的所有内容,但我目前正在尝试这段代码,它确实返回了正确的结果(11 行),由于 SQL 效率极低,它只需要 10 分钟。
var parents = (from p in db.PARENTs
where p.PARENT_ACTION
.Any(pa => pa.ACTION_ID == 99
&& pa.ACTION_DATE >= beginDate
&& pa.ACTION_DATE <= endDate
&& pa.ACTION_DATE == p.PARENT_ACTION.Max(pam => pam.ACTION_DATE))
select p);
我希望能够编写与下面的 SQL 非常相似的东西,它会在
select * from parent p
where p.STATUS = 99
and exists (select 'x' from parent_action pa
where pa.PARENT_ID = p.ID
and pa.ACTION_ID = 99
and pa.ACTION_DATE = (select max(pam.action_date)
from parent_action pam
where pam.parent_id = p.id)
and pa.action_date between to_date('04/10/2019', 'MM/DD/YYYY') and to_date('04/23/2019', 'MM/DD/YYYY'));
*****更新 1*****
我正在使用 System.Data.Entity 查询 Oracle 12c 数据库
Sample data:
STATUS
ID, DESC
1, ENTERED
2, SUBMITTED
99, COMPLETED
ACTIONS
ID, DESC
1, ENTER
2, SUBMIT
99, COMPLETE
PARENT
ID, STATUS
1, 99
2, 1
3, 99
4, 99
PARENT_ACTIONS
ID, PARENT_ID, ACTION_ID, ACTION_DATE
1, 1, 1, 04/01/2019
2, 1, 2, 04/05/2019
3, 1, 99, 04/11/2019
4, 2, 1, 04/11/2019
5, 3, 1, 04/15/2019
6, 3, 2, 04/16/2019
7, 3, 99, 04/17/2019
8, 3, 2, 04/18/2019 --Parent sent back to submitted status
9, 4, 1, 04/01/2019
10, 4, 2, 04/11/2019
11, 4, 99, 04/15/2019
12, 4, 99, 04/24/2019 --Completion details updated by customer, business rules require a new complete action be written
基于此示例数据,日期范围为 2019 年 4 月 10 日至 2019 年 4 月 23 日,我想写一些仅返回父 ID 1 的内容,因为这是唯一具有最大操作日期的父是 1) 一个 COMPLETE 操作 (99) 和 2) 在指定日期范围之间。我希望将 Parent 4 排除在外,因为最大操作日期不在指定的日期范围内。
***** 更新 2 *****
看起来我确实有正确的代码来返回所需的结果;但是,我认为我做错了什么,因为查询执行超过了 10 分钟。经过进一步调查,我似乎是生成的 SQL 中出现的“CAST AS”的另一个受害者,并大大降低了性能。在我的情况下,它将我在 SQL 中的 ID 列转换为数字 (10,0),当我的表中的 ID 列是整数时,在我的 EF 模型中,ID 列是 Int32。我不太确定如何解决这个问题,或者我是否应该为这个特定的数据需求编写自己的 SQL。
【问题讨论】:
-
您能否提供表架构、示例数据和预期输出?还有你使用的是什么 dbms(MSSQL、MySQL 等)?
标签: c# entity-framework linq-to-entities