我正在尝试学习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查询中指定它。
答案 0 :(得分:2)
如果我没记错的话,VB.NET将-1视为布尔值True,而SQL将+1视为布尔值True。因此,减号是VB.NET正确解释active_report字段所必需的。
答案 1 :(得分: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始终做正确的事。检查它的工作!