2

我正在尝试学习 LINQ to SQL。我遇到了一些我不明白的事情。这是 LINQ 程序(vb.net):

Imports System.IOModule Module1    
Sub Main()
        Dim crs = New DataClasses1DataContext()
        Dim sw As New StringWriter()
        crs.Log = sw
        Dim reports = From report In crs.CRS_Report_Masters
                      Group report By report_id = report.Report_ID Into grouped = Group
                      Select New With {
                          .reportId = report_id,                          
                         .two = grouped.Sum(
                              Function(row) row.active_report * row.Report_ID)
                          }
        For Each report In reports
            Console.WriteLine("{0} {1}", report.reportId, report.two)
        Next        
MsgBox(sw.GetStringBuilder().ToString())    
End Sub
End Module

这是它产生的 SQL:

SELECT SUM([t1].[value]) AS [two], [t1].[Report_ID] AS [reportId]  FROM (
      SELECT (-(CONVERT(Float,[t0].[active_report]))) *
            (CONVERT(Float,CONVERT(Float,[t0].[Report_ID]))) AS [value], [t0].[Report_ID]
      FROM [dbo].[CRS_Report_Master] AS [t0]
      ) AS [t1]  GROUP BY [t1].[Report_ID]
  -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1

我不明白为什么括号中的数学之前的 SQL 中有一个减号。我没有在 LINQ 查询中指定。

4

2 回答 2

2

如果我没记错的话,VB.NET 将 -1 视为 Boolean True,而 SQL 将 +1 视为 Boolean True。因此,减号是 VB.NET 正确解释 active_report 字段所必需的。

于 2012-06-07T21:09:16.620 回答
1

所以,现在我明白发生了什么。对应于 SQL 位的列的 LINQ to SQL 定义是一个 .net 布尔值。很公平。但是,在使用它进行数学运算时,编译器会否定 ekolis 所描述的值。我没想到——事实上我认为这是一个错误,因为我没有得到我期望的结果。例如,如果active_report=1 和report_id=123,我希望得到“123”,但我得到的是“-123”。我修改了这样的查询:

Dim reports = (From report In crs.CRS_Report_Masters
                  Group report By report_id = report.Report_ID Into grouped = Group
                  Select New With {
                      .reportId = report_id,
                      .two = grouped.Sum(
                          Function(row) If(row.active_report, 1, 0) * CInt(row.Report_ID))
                      })

将生成的 SQL 更改为:

SELECT SUM([t1].[value]) AS [two], [t1].[Report_ID] AS [reportId]  FROM (
      SELECT (
          (CASE
              WHEN (COALESCE([t0].[active_report],@p0)) = 1 THEN @p1
              ELSE @p2
           END)) * (CONVERT(Int,[t0].[Report_ID])) AS [value], [t0].[Report_ID]
      FROM [dbo].[CRS_Report_Master] AS [t0]
      ) AS [t1]  GROUP BY [t1].[Report_ID]
  -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [0]
  -- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [1]
  -- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [0]
  -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1

我想这是有道理的,尽管这是一种获得预期结果的迂回方式。我相信,在 T-SQL 中,一个简单的 SELECT [BOOLEAN]*[INTEGER] 将达到相同的结果。经验教训:不要相信 LINQ 总是做正确的事。检查它的工作!

于 2012-06-08T13:33:11.727 回答