LINQ for RANK()和CASE WHEN在VB.NET中

时间:2014-02-10 23:34:48

标签: vb.net linq sql-order-by case-when

我很抱歉,如果已经在 VB.Net 中针对 RANK() CASE WHEN 提出了类似的问题。

我有两张桌子。包含所需列的脚本如下:

表1:

SELECT S.* INTO dbo.LoanHeader
FROM
(
    SELECT 1 LoanHeaderId, 1234 LoanNumber, GETDATE() EffectiveOn
    UNION ALL
    SELECT 2 LoanHeaderId, 2234 LoanNumber, GETDATE() EffectiveOn
    UNION ALL
    SELECT 3 LoanHeaderId, 3234 LoanNumber, GETDATE() EffectiveOn
)S

表2:

SELECT S.* INTO dbo.LoanHeaderHistory
FROM
(
    SELECT 1 LoanHeaderId, 1 NewValue, 'LoanReviewStatusId' ColumnName, DATEADD(DD, -3, GETDATE()) EnteredDate
    UNION ALL
    SELECT 1 LoanHeaderId, 2 NewValue, 'LoanReviewStatusId' ColumnName, DATEADD(DD, -2, GETDATE()) EnteredDate
    UNION ALL
    SELECT 1 LoanHeaderId, 3 NewValue, 'LoanReviewStatusId' ColumnName, DATEADD(DD, -1, GETDATE()) EnteredDate
    UNION ALL
    SELECT 1 LoanHeaderId, 1 NewValue, 'LoanReviewStatusId' ColumnName, GETDATE() EnteredDate
)S

我想在下面的SQL中编写一个 LINQ语句在VB.Net 中。还有其他表格,如果我开始提到为什么我需要它这样做将花费太长时间。但目的是在标准中使用基于NewValue的日期之一:

SELECT
    LH.LoanHeaderId,
    LHH.NewValue,
    LHH.EnteredDate
FROM dbo.LoanHeader LH
LEFT JOIN 
(
    SELECT
        LoanHeaderId,
        NewValue,
        EnteredDate,
        RANK() OVER (PARTITION BY LoanHeaderId ORDER BY EnteredDate DESC) HRank
    FROM dbo.LoanHeaderHistory
    WHERE ColumnName = 'LoanReviewStatusId'
)LHH ON LHH.LoanHeaderId = LH.LoanHeaderId AND LHH.HRank = 1
WHERE CASE WHEN ISNULL(LHH.NewValue, 1) IN (2, 3) THEN LHH.EnteredDate ELSE LH.EffectiveOn END >= LH.EffectiveOn

我开始这样做:

Dim columnName = "LoanReviewStatusId"
Dim query = (From lh In e.LoanHeaderEntities_
             From lhh In e.LoanHeaderHistoryEntities.OrderByDescending(Function(i) i.EnteredDate).Where(Function(i) lh.LoanHeaderId = i.LoanHeaderId AndAlso i.ColumnName = columnName).DefaultIfEmpty() _
             Select New With{ _
                     lh.LoanHeaderId, _
                     lhh.NewValue, _
                     lhh.EnteredDate _
                     })
query = query.Where(Function(i) If(Not IsNothing(i.LoanReviewStatusId) AndAlso (i.LoanReviewStatusId = 2 Or i.LoanReviewStatusId = 3), i.LoanStatusChangedDate, i.EffectiveOn) >= i.EffectiveOn)
Return query.ToList()

1 个答案:

答案 0 :(得分:0)

哈!我做的。我从here找到了一些有用的信息。

VB.Net代码是

Dim query = (From lh In e.LoanHeaderEntities _
         From lhhGrp In e.LoanHeaderHistoryEntities.Where(Function(i) i.ColumnName = colName And i.LoanHeaderId = lh.LoanHeaderId) _
        .OrderByDescending(Function(i) i.EnteredDate) _
        .Take(1) _
        .DefaultIfEmpty() _     
         Select New HeaderInfo With {_
             .LoanHeaderId = lh.LoanHeaderId, _             
             .EffectiveOn = lh.EffectiveOn, _
             .LoanStatusChangedDate = lhhGrp.EnteredDate, _
             .LoanReviewStatusId = lhhGrp.NewValue _
            })
'Additional condition for CASE WHEN
If (isActive) Then
    query = query.Where(Function(i) If(i.LoanReviewStatusId = LoanReviewStatus.Final Or i.LoanReviewStatusId = LoanReviewStatus.Completed, i.LoanStatusChangedDate, i.EffectiveOn) >= i.EffectiveOn)
End If
Return query.ToList()

当我看到它在幕后执行的查询时,我无法停止笑。检查它在下面生成的CASE WHEN语句。我忽略了ISNULL,因为我的字段不是NULL。

SELECT
    [Extent1].LoanHeaderId,
    [Limit1].NewValue,
    [Limit1].EnteredDate
FROM [dbo].[LoanHeader] AS [Extent1]
OUTER APPLY
(
    SELECT TOP (1)
        [Project1].[LoanHeaderId] AS [LoanHeaderId],
        [Project1].[NewValue] AS [NewValue],
        [Project1].[EnteredDate] AS [EnteredDate]
        FROM
        (
            SELECT
                [Extent2].[LoanHeaderId] AS [LoanHeaderId], 
                [Extent2].[NewValue] AS [NewValue], 
                [Extent2].[EnteredDate] AS [EnteredDate]
            FROM [dbo].[LoanHeaderHistory] AS [Extent2]
            WHERE ([Extent2].[ColumnName] = 'LoanReviewStatusId')
            AND ([Extent2].[LoanHeaderId] = [Extent1].[LoanHeaderId])
        )  AS [Project1]
        ORDER BY [Project1].[EnteredDate] DESC
) AS [Limit1]
WHERE ((CASE WHEN ((CASE WHEN (CASE WHEN ((3 =  CAST( [Limit1].[NewValue] AS int)) OR (2 =  CAST( [Limit1].[NewValue] AS int))) THEN cast(1 as bit) WHEN ( NOT ((3 =  CAST( [Limit1].[NewValue] AS int)) OR (2 =  CAST( [Limit1].[NewValue] AS int)))) THEN cast(0 as bit) END IS NULL) THEN cast(0 as bit) WHEN ((3 =  CAST( [Limit1].[NewValue] AS int)) OR (2 =  CAST( [Limit1].[NewValue] AS int))) THEN cast(1 as bit) WHEN ( NOT ((3 =  CAST( [Limit1].[NewValue] AS int)) OR (2 =  CAST( [Limit1].[NewValue] AS int)))) THEN cast(0 as bit) END) = 1) THEN  CAST( [Limit1].[EnteredDate] AS datetime) ELSE  CAST( [Extent1].[EffectiveOn] AS datetime) END) >=  CAST( [Extent1].[EffectiveOn] AS datetime))

告诉我谁更好地撰写查询,EF或我?