【问题标题】:LINQ for RANK() and CASE WHEN in VB.NET用于 RANK() 的 LINQ 和 VB.NET 中的 CASE WHEN
【发布时间】:2014-02-10 23:34:47
【问题描述】:

抱歉,如果 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

我想在VB.Net中写一个LINQ语句下面的SQL。还涉及其他表,如果我开始提到为什么我需要它,那将花费太长时间。但目的是使用基于条件中的 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()

【问题讨论】:

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


    【解决方案1】:

    哈!我做到了。我从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 还是我?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-02
      • 2019-09-26
      • 1970-01-01
      • 1970-01-01
      • 2021-08-18
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多