Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么linqtosql错误地删除了我的union中的字段?_C#_Linq To Sql_.net 3.5 - Fatal编程技术网

C# 为什么linqtosql错误地删除了我的union中的字段?

C# 为什么linqtosql错误地删除了我的union中的字段?,c#,linq-to-sql,.net-3.5,C#,Linq To Sql,.net 3.5,我正在尝试将多个查询聚合在一起,以便使用通用数据结构为我的用户提供最新的更新显示。在我的第一个函数中,我有以下select子句: .Select(x => new PlayerUpdateInfo { FirstName = x.PodOptimizedSearch.FirstName, LastName = x.PodOptimizedSearch.LastName, RecruitId = x.RecruitId, Date = x.Date,

我正在尝试将多个查询聚合在一起,以便使用通用数据结构为我的用户提供最新的更新显示。在我的第一个函数中,我有以下select子句:

.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个,从而导致错误匹配

为什么linqtosql错误地生成联合,我如何解决这个问题

编辑:

好的,这个问题似乎涉及到.NET3.5的Linq到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
                             });
    }
在.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中解决这个问题吗?

这是一个更新的答案-在3.5中,优化似乎无法关闭。我在LinqPad中尝试了很多方法,只要有一个C表达式不是从列派生的,查询编译器就会将其从SQL中删除

所以我们需要一些从列表达式派生的东西,但我们可以强制它始终为null

这里有一个解决方案,我已经能够开始工作-编写一个条件表达式,当一个列值等于它本身时返回null;因此总是返回null。这不会很好,因为3.5中的Linq to Sql在优化查询时表现得非常积极,我们必须对每个需要的null使用唯一的比较,例如使用==in one,then!=下一步等等;当我们修改它来处理空值时,它会变得更加丑陋,如果你必须对一个可空的列进行这种攻击:

我只是从您的代码中挑选出可以看到的列名,但您可能希望使用不同的列名:

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 = recruit.FirstName = recruit.FirstName ? null : "",  
  UpdateComments = recruit.FirstName != recruit.FirstName ? "" : null,  
  TeamId = recruit.LastName = recruit.LastName ? null : "",  
  State = recruit.LastName != recruit.LastName ? "" : null
};
在LinqPad中,我在生成的SQL中为使用?:”的每个语句获取一个列表达式。表达式的另一方面是因为SQL抱怨CASE语句有多个null

很明显,这个解决方案除了像sin一样难看之外,还取决于有多少列可供您进行这些伪比较,以及L2S映射了多少个唯一的比较

团队、更新注释、状态为空字符串或空。因此,您应该为这两种情况提供相同的值。 如果使用默认比较器,则UpdateMessage不同,因此对象也不同。所以你可以用concat代替union。
有趣的问题。你试过做一个超级简单的例子吗?你能在简化的例子中重现同样的问题吗?试着用一个有9个参数的构造函数代替。也许LINQ的行为会有所不同。你能在Anon上联合,并在联合后转换到PlayerUpdateInfo吗?这不是答案,但我想知道这是否是创建优化的SelectAs PlayerUpdateInfo。我无法在一个简单的示例中得到错误,但是它看起来像null和string。select中的空文本在对待null时会有一些不同,“select null as[field]”和“select@p0 as[field]”时会有一个string.Empty参数。我猜GetFirstQuery和GetSecondQuery都返回IQueryable?刚到家,我会看看是否能想出一个发生这种情况的简单例子。是的,这两个函数都返回IQueryableYeah,这就是我知道这是一个与常数相关的优化,因为在同一个select语句中使每个常数不同会改变字段的数量。问题是它需要我做一些事情,比如把其中一个字段变成一个空格,这会改变queryoh的意思。我要说的是,nullstring技巧不起作用,它仍然在优化:该死,我们必须尝试不同的值then@KallDrexx-已更新我的答案。LINQtoSQL3.5查询编译器在优化方面表现得非常出色;我想我已经找到了一个解决办法,但它太肮脏了。
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 = recruit.FirstName = recruit.FirstName ? null : "",  
  UpdateComments = recruit.FirstName != recruit.FirstName ? "" : null,  
  TeamId = recruit.LastName = recruit.LastName ? null : "",  
  State = recruit.LastName != recruit.LastName ? "" : null
};