我正在尝试将多个查询聚合在一起,以便使用通用数据结构为我的用户提供最新的更新显示以提供联合支持。在我的第一个函数中,我有以下选择子句:
.Select(x => new PlayerUpdateInfo
{
FirstName = x.PodOptimizedSearch.FirstName,
LastName = x.PodOptimizedSearch.LastName,
RecruitId = x.RecruitId,
Date = x.Date,
UpdateMessage = x.IsAddedAction
? "Player was added to this recruiting board by " + x.Person.FirstName
+ " " + x.Person.LastName
: "Player was removed from this recruiting board by " +
x.Person.FirstName + " " + x.Person.LastName,
// Defaults for union support
Team = string.Empty,
UpdateComments = x.Comments,
TeamId = 0,
State = string.Empty
});
当调用它时,它会正确生成一个返回 9 个字段的查询。第二种方法的选择是:
select new PlayerUpdateInfo
{
FirstName = recruit.FirstName,
LastName = recruit.LastName,
RecruitId = recruit.RecruitId,
Date = asset.CreateDate,
UpdateMessage = "New Full Game Added",
// Defaults for union support
Team = null,
UpdateComments = null,
TeamId = 0,
State = null
};
当此查询自行运行时,它会正确返回 9 个值。但是,当我尝试做
var query = GetFirstQuery();
query = query.union(GetSecondQuery());
我得到一个查询失败的 sql 异常,因为所有查询都没有相同数量的字段。调查生成的 SQL 表明第一个查询是正确的,但 Linq 正在生成第二个(联合)查询,只有 7 个字段。经过测试,Linq 似乎正在“优化”空值,因此它只返回一个空列而不是 3,从而导致不匹配。
为什么 Linq-to-sql 错误地生成联合,我该如何解决这个问题?
编辑:
好的,这个问题似乎与.Net 3.5 的 Linq-to-Sql 中的联合链接有关。这显然不会发生在 4 中。使用以下代码:
protected IQueryable<PlayerUpdateInfo> Test1()
{
return PodDataContext.Assets
.Select(x => new PlayerUpdateInfo
{
Date = DateTime.Now,
FirstName = x.Title,
LastName = string.Empty,
RecruitId = 0,
State = string.Empty,
Team = string.Empty,
TeamId = 0,
UpdateComments = string.Empty,
UpdateMessage = string.Empty
});
}
protected IQueryable<PlayerUpdateInfo> Test2()
{
return PodDataContext.SportPositions
.Select(x => new PlayerUpdateInfo
{
Date = DateTime.Now,
FirstName = string.Empty,
LastName = x.Abbreviation,
RecruitId = 0,
State = string.Empty,
Team = string.Empty,
TeamId = 0,
UpdateComments = string.Empty,
UpdateMessage = string.Empty
});
}
然后我通过以下方式联合链: var q2 = Test1().Union(Test2()).Union(Test1());
在 .Net 3.5 中,我得到以下 sql,它不匹配并且失败
SELECT [t4].[value] AS [RecruitId], [t4].[Title] AS [FirstName], [t4].[value2] AS [LastName], [t4].[value22] AS [Team], [t4].[value3] AS [Date]
FROM (
SELECT [t2].[value], [t2].[Title], [t2].[value2], [t2].[value2] AS [value22], [t2].[value3]
FROM (
SELECT @p0 AS [value], [t0].[Title], @p1 AS [value2], @p2 AS [value3]
FROM [dbo].[Assets] AS [t0]
UNION
SELECT @p3 AS [value], @p4 AS [value2], [t1].[Abbreviation], @p5 AS [value3]
FROM [dbo].[SportPositions] AS [t1]
) AS [t2]
UNION
SELECT @p6 AS [value], [t3].[Title], @p7 AS [value2], @p8 AS [value3]
FROM [dbo].[Assets] AS [t3]
) AS [t4]
在 .net 4 中生成以下代码:
SELECT [t4].[value] AS [RecruitId], [t4].[Title] AS [FirstName], [t4].[value2] AS [LastName], [t4].[value3] AS [Team], [t4].[value4] AS [TeamId], [t4].[value5] AS [State], [t4].[value6] AS [UpdateMessage], [t4].[value7] AS [UpdateComments], [t4].[value8] AS [Date]
FROM (
SELECT [t2].[value], [t2].[Title], [t2].[value2], [t2].[value3], [t2].[value4], [t2].[value5], [t2].[value6], [t2].[value7], [t2].[value8]
FROM (
SELECT @p0 AS [value], [t0].[Title], @p1 AS [value2], @p2 AS [value3], @p3 AS [value4], @p4 AS [value5], @p5 AS [value6], @p6 AS [value7], @p7 AS [value8]
FROM [dbo].[Assets] AS [t0]
UNION
SELECT @p8 AS [value], @p9 AS [value2], [t1].[Abbreviation], @p10 AS [value3], @p11 AS [value4], @p12 AS [value5], @p13 AS [value6], @p14 AS [value7], @p15 AS [value8]
FROM [dbo].[SportPositions] AS [t1]
) AS [t2]
UNION
SELECT @p16 AS [value], [t3].[Title], @p17 AS [value2], @p18 AS [value3], @p19 AS [value4], @p20 AS [value5], @p21 AS [value6], @p22 AS [value7], @p23 AS [value8]
FROM [dbo].[Assets] AS [t3]
) AS [t4]
那是有效的sql并且有效。由于各种原因,我们无法将生产系统升级到 .net 4,有没有人知道我可以在 .net 3.5 中解决这个问题的方法?