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をブールTrueとして扱い、SQLは+1をブールTrueとして扱います。したがって、VB.NETがactive_reportフィールドを適切に解釈するには、マイナス記号が必要です。

于 2012-06-07T21:09:16.620 に答える
1

だから、今私は何が起こっているのかを見る。SQLビットに対応する列のLINQtoSQL定義は、.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 に答える