代码之家  ›  专栏  ›  技术社区  ›  Andrew Barrett

在选择匿名类型时被Linq2 SQL行为混淆

  •  1
  • Andrew Barrett  · 技术社区  · 15 年前

    我真的被我看到的林肯的行为搞糊涂了,这给我带来了麻烦。

    我写了一个问题,比如:

    var reportalerts = pushDB.ReportAlerts
                             .Select(p => new {p.Title, p.Url, p.DateStamp})
                             .OrderBy(p => p.DateStamp)
                             .Take(numResultsPerPage);
    

    这将创建我期望的SQL:

    SELECT TOP (5) [t0].[Title], [t0].[Url], [t0].[DateStamp]
    FROM [dbo].[ReportAlerts] AS [t0]
    ORDER BY [t0].[DateStamp]
    

    如果我再向匿名类型添加一个额外的属性,则生成的SQL将完全不同:

    var reportalerts = pushDB.ReportAlerts
                             .Select(p => new {p.Title, p.Url, p.DateStamp, p.Text})
                             .OrderBy(p => p.DateStamp)
                             .Take(numResultsPerPage);
    

    变成:

    SELECT TOP (5) [t0].[Title], [t0].[Url], [t0].[DateStamp], [t0].[PushReportAlertID], [t0].[DateOfAlert], [t0].[AlertProductID], [t0].[Description], [t0].[Mpid], [t0].[UIName], [t0].[CustomerDesc], [t0].[ProductArea]
    FROM [dbo].[ReportAlerts] AS [t0]
    ORDER BY [t0].[DateStamp]
    

    也就是说,它现在从表中取出每一列。就好像它已经决定了,这家伙选择了足够多的专栏,让我现在就去拿所有的专栏。这对我来说是个问题,因为我想用另一个具有不同列的表中的类似查询来连接(即union all)。(在ORDER BY/TAKE之前)如果它只接受由我的匿名类型属性指定的列,这不会是问题,但是由于它接受了所有列,并且两个表具有不同的列,所以它失败了。

    我可以用各种不同的方法来解决这个问题,所以我不想被这个问题打断,我只是想了解上面发生了什么,如果没有方法,你可以让它返回你想要的列。

    1 回复  |  直到 15 年前
        1
  •  1
  •   Andrew Barrett    15 年前

    加,因为我是个白痴。

    问题是,文本不是表上的属性,它满足一个接口,并实际返回表中的另一个属性。

    将上述内容更改为:

    var reportalerts = pushDB.ReportAlerts
                             .Where(p => subscribedMpids.Contains(p.Mpid))
                             .Select(p => new {p.Title, p.Url, p.DateStamp, Text = p.Description})
                             .OrderBy(p => p.DateStamp)
                             .Take(numResultsPerPage);
    

    按预期工作。