这是一个例子:
假设我有 3 张表,国家、人和城市。城市记录具有标识国家/地区的不可为空的外键字段。人员记录有一个可以为空的外键字段来标识一个国家 - 他们可能来自一个不再存在的东欧国家。
我想从人员列表和城市列表中创建国家/地区的组合列表:
var people = dbContext.People.Where(...);
var cities = dbContext.Cities.Where(...);
var countries = cities.Select(c=>c.Country);
countries = countries.Union(people.Select(p=>p.Country));
问题来自最后一行。由于并非所有人员记录都具有匹配的国家/地区记录,因此 LINQ 正在(正确地)创建一个查询,以确保每个无国籍人都有一个填充空的行。使用调试器,这似乎是通过创建一个 entra 虚拟列调用“[test]”来完成的
SELECT [t2].[test], [t2].[CountryID], [t2].[Name]
FROM [dbo].[People] AS [t0]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t1].[CountryID], [t1].[Name]
FROM [dbo].[Countries] AS [t1]
) AS [t2] ON [t2].[CountryID] = [t0].[CountryID]
虽然额外的列 [test] 在代码端被静默删除(结果被标识为 IQueryable),但在 SQL 端它肯定存在,并且当我将它与正常的 Country 选择联合时导致查询被拒绝陈述。
在最后一种情况下,我不想要或不需要额外的虚拟行 - 在我已经包含people.Where(p=>p.CountryID != null).Select(p=>p.Country)
并尝试的完整程序中p=>Country != null
。
但是 Linq 不承认这会阻止空行,因此仍然插入测试列。由于测试列是不可见的,因此我没有明显的方法可以将其从其他报告为 IQueryable 对象的内容中“删除”。最终结果是关于我的 UNION 构造具有不相等的列数的运行时错误。
如何在我的可空关系上强制执行 INNER JOIN,或者通过排除不可见的测试列使联合工作按我的意愿工作?