实体框架在同一张表中查询 WHERE 中的步骤顺序

Posted

技术标签:

【中文标题】实体框架在同一张表中查询 WHERE 中的步骤顺序【英文标题】:Entity Framework query the same table for the sequence of steps in WHERE 【发布时间】:2021-10-05 23:39:21 【问题描述】:

我有以下 EF 代码头等舱来跟踪该人在机场的到达状态。在每次检查中,记录都会插入到这个表中。以下是演示流程的步骤。

Landed -> FirstCheck Approved -> Clearance Approved -> Arrived
Landed -> FirstCheck Approved -> Clearance Approved -> Security Check -> Denied // This is the one I need to query
Landed -> FirstCheck Approved -> Clearance Approved -> Security Check -> Arrived

我需要找到 FirstCheck Approved 和 SecurityCheck 的被拒绝记录来跟踪原因。

public class ArrivalStatusLog

    public ArrivalStatusLog();
    public int ArrivalStatusLogId  get; set; 
    public int PersonNumber get; set; 
    public DateTime CreationDate  get; set; 
    public string Status  get; set; 

EF 查询

var denialPersons = await db.ArrivalStatusLogs
                            .Where(s => s.Status == "Denied") // Additional filter
                            .Select(x => x.PersonNumber)

对于具有其他状态的给定人员,如何对同一表中的其他记录执行 AND 条件?在我的情况下,我需要找到 Denied,然后是 FirstCheck Approved 和 Security Check。

【问题讨论】:

如果同一个人多次旅行、过去被完全接受、后来被拒绝,您将如何检测?还是过去被拒绝,后来又接受了? 【参考方案1】:

您可以使用.Any() 查找同一个人的所有记录,其中存在另一条状态为被拒绝的记录:

var denialPersons= await db.ArrivalStatusLogs
          .Where(s => db.ArrivalStatusLogs.Any(d => d.PersonNumber == s.PersonNumber && d.Status == "Denied")) // Additional filter
          .Select(x=> x.PersonNumber);

我认为 .Select() 在这里是多余的,实际上您只需要原始记录,以及创建日期和状态,但以防万一您只需要它。

生成的 SQL 类似于:

SELECT  PersonNumber
FROM    ArrivalStatusLogs AS s
WHERE   EXISTS
        (   SELECT  1
            FROM    ArrivalStatusLogs AS d
            WHERE   d.PersonNumber = s.PersonNumber
            AND     d.Status = 'Denied'
        );

如果您只想选择您想要的第一条检查记录,那么您需要一个进一步的过滤器,例如

var denialPersons= await db.ArrivalStatusLogs
          .Where(s => s.Status == "FirstCheck Approved" && 
                        db.ArrivalStatusLogs.Any(d => d.PersonNumber == s.PersonNumber 
                                    && d.Status == "Denied")) // Additional filter
          .Select(x=> x.PersonNumber);    

相当于:

SELECT  PersonNumber
FROM    ArrivalStatusLogs AS s
WHERE   s.Status = 'FirstCheck Approved'
AND     EXISTS
        (   SELECT  1
            FROM    ArrivalStatusLogs AS d
            WHERE   d.PersonNumber = s.PersonNumber
            AND     d.Status = 'Denied'
        );

【讨论】:

以上是关于实体框架在同一张表中查询 WHERE 中的步骤顺序的主要内容,如果未能解决你的问题,请参考以下文章

使用 Android 房间数据库在同一张表中的一对多关系

如何从同一张表中优化几个“WHERE(Select ....)= value”

SQL中的每一张表都必须设有主键吗

查询获取同一张表中1:N关系的数据

Laravel where 条件 - pgsql 查询

在oracle中怎么把一张表的数据插入到另一张表中