实体框架过滤与给定表中任何记录都不匹配的Id

问题描述 投票:0回答:2

在实体框架(在单个查询中)中,我如何传递 ID 列表并过滤表中没有任何匹配记录的 ID? (从传递的Id列表中检索没有任何记录的Id)

例如,在公司拥有多个资产的情况下,我可以执行类似的操作来检查特定公司是否没有资产(当收到错误时)。当我们只想检查一条记录时,这是可以的。

await _dbContext.Assets.AnyAsync(a => a.CompanyId == companyId);

只是尝试从给定列表中进行过滤。例如,资产表包含 companyId 100102 的记录。如果我使用以下列表执行 SQL“IN”,只是想获取在资产表中没有任何记录的 Id 101103

List<int> companyIds = new List<int> { 100, 101, 102, 103 };

await _dbContext.Assets.Include(a => a.Company)
            .Where(a => !companyIds.Contains(a.Company.CompanyId))
            .Select(a => a.Company).ToListAsync()
c# .net sql-server entity-framework entity-framework-core
2个回答
0
投票

首先根据列表中传递的公司 ID 过滤公司列表。 那么,

Where(c => !_dbContext.Assets.Any(a => a.CompanyId == c.CompanyId))

使用此功能,我们确保只选择资产表中没有任何匹配记录的公司。


0
投票

一般来说,此类任务需要自上而下的查询,而不是自下而上的查询。自下而上的查询不仅在实现所需的过滤条件时存在问题,而且还会在结果集中产生重复项,因为您正在查询多侧,然后选择一侧。

因此,如果您想从列表中获取具有 Id 且没有资产的公司,那么就这样做,例如

List<int> companyIds = new List<int> { 100, 101, 102, 103 };

var query = _dbContext.Companies
    .Where(c => companyIds.Contains(c.CompanyId))
        && !c.Assets.Any());        

目标非常简单、合乎逻辑且易于理解。如果您只需要 id,则只需在查询末尾添加

.Select(c => c.CompanyId)
即可。

这里唯一的假设是您具有逆向集合导航属性,通常您应该具有逆向集合导航属性,以便能够编写此类查询。如果您不这样做,那么您可以通过将

!c.Assets.Any()
替换为类似

的老式/纯 LINQ 方式来完成此操作
!_dbContext.Assets.Any(a => a.CompanyId == c.CompanyId)
© www.soinside.com 2019 - 2024. All rights reserved.