LINQ:为什么联合引发错误消息" IQueryable< ...>不包含' Union'"的定义?

时间:2018-03-20 13:23:35

标签: c# sql-server linq

问题是关于 LINQ中的嵌套联合:我想要合并来自3个不同数据库中的表的数据,并将它们显示在一个结果表中。

为了明确我想要实现的目标,我将展示如何在SQL中完成(我正在使用Northwind,Nutshell和Pubs数据库,因此您可以更轻松地自行尝试):

SELECT 'Territories' as [Table], TerritoryDescription as Item, RegionID as ID 
  FROM Northwind.dbo.Territories
UNION
SELECT 'MedicalArticles' as [Table], Topic as Item, ID as ID  
  FROM Nutshell.dbo.MedicalArticles
UNION
SELECT 'Authors' as [Table], City as Item, Zip as ID 
  FROM pubs.dbo.Authors

基础表结构是: table structure 此查询正常工作没有错误,并返回一个包含3列(表,项和ID)的表,结合3个表区域,医学文章和作者的数据:

Result

如果您为3个选择语句中的每一个添加top 3,那么您将获得:

ResultTop3

现在我通过编写如下代码在 LINQ 中尝试了相同的内容:

void Main()
{
    // In LinqPad:
    // Drag + Drop databases from Schema explorer to code window with pressed Ctrl key
    var dc = this; // database context: Northwind + Nutshell + pubs

    // first database Northwind is default
    var q1 = (from s in dc.Territories select new { Table = "Territories", 
                Item = s.TerritoryDescription, ID = s.RegionID }).Distinct().Take(5); 

    // second database .Nutshell needs to be referenced
    var q2 = (from s in dc.Nutshell.MedicalArticles select new { Table="MedicalArticles", 
                Item = s.Topic, ID=s.ID }).Distinct().Take(5); 

    // third database .Pubs needs to be referenced
    var q3 = (from s in dc.Pubs.Authors select new { Table = "Authors", 
                Item = s.City, ID = s.Zip }).Distinct().Take(5); 

    // union q1 with q2 works
    var u1 = q1.Union(q2.Select(s => s)); u1.Dump();

    // but union u1 with q3 does not work
    //var u2 = u1.Union(q3.Select(s => s)); u2.Dump();      
}

第一个联合(q1和q2)工作正常 - 但我不能将第三个查询q3应用于结果(即u1.Union(q3.Select(s => s))不起作用)。

当我取消注释查询u2的行时,我收到的错误消息并不是非常有用:

  

CS1929 'IQueryable<<anonymous type: string Table, string Item, int ID>>' does not contain a definition for 'Union' and the best extension method overload 'ParallelEnumerable.Union<<anonymous type: string Table, string Item, string ID>>(ParallelQuery<<anonymous type: string Table, string Item, string ID>>, IEnumerable<<anonymous type: string Table, string Item, string ID>>)' requires a receiver of type 'ParallelQuery<<anonymous type: string Table, string Item, string ID>>'

如何解决错误?

注意:以上示例可以在LinqPad中试用。只需将代码放在一个窗口中,然后按住Ctrl键添加3个数据库Northwind,NutShell和Pubs,然后将数据库拖放到查询窗口。

1 个答案:

答案 0 :(得分:2)

非常感谢所有在评论中做出贡献的人! 我根据Ivansgmoore的评论创建了这个答案:

“很可能匿名类型投影中ID属性的类型不同。请检查RegionIDZip的类型。” - Ivan

“错误消息显示Zip是字符串,而RegionID是int。解决方法是将ID = s.RegionID更改为 ID = s.RegionID.ToString() ID=s.ID ID=s.ID.ToString() 。“ - sgmoore

这绝对是解决方案。看起来,C#中的类型检查比SQL更严格(回顾一下,在SQL中,union没有任何额外的类型转换)。

但错误信息肯定是误导性的(“IQueryable&lt;&gt;”不包含“联盟”的定义),这就是问题的原因。更有意义的错误消息在这里会有所帮助。