问题是关于 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
底层表结构为: 该查询工作正常,没有错误,并返回一个包含 3 列(表、项目和 ID)的表,组合了来自 3 个表 Territories、MedicalArticles 和 Authors 的数据:
如果您向 3 个 select 语句中的每一个添加
top 3
,您将得到:
现在我在 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,然后将数据库拖放到查询窗口即可。
非常感谢所有在评论中做出贡献的人! 我根据 Ivan 和 sgmoore 的评论创建了这个答案:
“匿名类型投影中
ID
属性的类型很可能不同。检查 RegionID
和 Zip
的类型。” - Ivan
“错误消息显示
Zip
是字符串,而 RegionID
是整数。解决方法是将 ID = s.RegionID
更改为 ID = s.RegionID.ToString()
,将 ID=s.ID
更改为 ID=s.ID.ToString()
。” - 斯格摩尔
这绝对是解决方案。看起来,C# 中的类型检查比 SQL 中更严格(回顾一下,在 SQL 中,联合工作无需任何额外的类型转换)。
但是错误消息肯定具有误导性(“IQueryable <>”不包含“Union”的定义”),这就是提出问题的原因。更有意义的错误消息在这里会很有帮助。