2009-09-01 62 views
1

这里LINQ和可空的主要关系是aň前a mple:影响UNION操作

让ŞaŸI H a已经3吨a统计局,国家,人民a次城市。市记录^ h a已经a非空a BLE外键字段识别a国家。人们记录^ h a已经a 空a BLE外键字段识别a国家 - 他们中号a y为从a否E a船尾欧洲aň全国第a t无不复存在。

I W a NT到CRE a TE a国家的组合列表,从列表a人a次城市a名单:

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)); 

的问题来自于日a T L a第一行。由于没有a LL人记录^ h a已经a米a tching全国纪录,LINQ是(正确)CRE a婷a查询日a牛逼确保不会a行用空值填充每一个countryless人。与a调试它a PPE a RS,这是通过CRE a婷aÑENTR a虚设列c a LL “[测试]”

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] 

虽然第a吨抽a柱[测试]被静默去除(完成结果被标识为a s IQuery a ble)在代码方,在SQL方面它是绝对存在的,and当我将它与a标准联合时导致查询被拒绝a升选择国家ST a tement。

在鳍a L C a本身我不W¯¯a NT或需要抽a虚拟行 - 在全PROGR a M I已经a LRE a DY包括people.Where(p=>p.CountryID != null).Select(p=>p.Country) a一报还一a在试着p=>Country != null

然而,Linq不承认th a t这将防止空行and因此仍然插入测试列。 a S上的测试柱是看不见的,I H a已经没有明显的瓦特a y的WH a t被否则报告a小号aÑIQUERY a BLE对象“移除”它的。最终结果是运行时错误a回合我的UNION构造h a ving a n unequ a l列数。

如何Ça n个I强制aňINNER排除无形测试列JOIN对我的空a BLE相对a tionship,或以其他方式米a科工会工作a的I w^a NT到?

回答

1

我知道理想情况下你会使用映射中的关系,但这可能是一个很好的解决方法。

var people = dbContext.People.Where(...); 
var cities = dbContext.Cities.Where(...); 

var countryIds = 
    cities 
    .Select(c => c.CountryID) 
    .Union(people 
    .Select(p => p.CountryID) 
    .Where(cID => cID.HasValue) 
    .Select(cID => cID.Value)); 

var countries = dbContext.Countries 
    .Where(c => countryIds.Contains(c.CountryID));