首页 > 解决方案 > LINQ 和 EF Core 构建查询“不在”

问题描述

假设这 2 个简化表:

表一

public int OneId { get; set; }
public ICollection<TableTwo> TableTwo { get; set; }

有价值观

OneId
1
2
3

表二

public int OneId { get; set; }
public string Color {get; set; }
public int AnotherId {get; set; }
public TableOne TableOne { get; set; }

有价值观

OneId | Color | AnotherId
1     | Blue  | 9
1     | Green | 1
2     | Blue  | 1

我想得到的是所有TableOne这些都没有标记为Blueand AnotherId != 9

我可以在一个穷人的 2 步中做到这一点。首先得到我想要的相反:

var firstStep = await TableOne
    .AsNoTracking()
    .Where(o => o.TableTwo.Any(t => t.Color == "Blue" && t.AnotherId == '9'))
    .Select(o => o.OneId)
    .ToListAsync();

这给了我一个List<int>我可以做到的:

var secondStep = from a in TableOne
                 where !firstStep.Contains(a.OneId)
                 select a;

var finalResult = await secondStep.ToListAsync();

这将正确返回我正在寻找的内容:

OneId
2
3

1是唯一一个不符合标准的人,因为他是唯一一个用Blueand标记的人9

我不喜欢这种方法的是.Contains生成的 SQL。

SELECT `a`.`OneId`
FROM `TableOne` AS `a`
WHERE `a`.`OneId` NOT IN (1)

NOT IN部分可能有数千个值,并且生成的查询未参数化,从而使 CPU 不满意。

我怎样才能把它变成 aNOT EXISTS而不是 a NOT IN

标签: c#linqef-core-3.0

解决方案


推荐阅读