簡體   English   中英

C#SQL到Linq-翻譯

[英]C# SQL to Linq - translation

我有一個帶有交易記錄的表,類似於:

--REQUEST_ID----ITEM_ID----ITEM_STATUS_CD----EXECUTION_DTTM       
     1             1            1          2016-08-29 12:36:07.000   
     1             2            0          2016-08-29 12:37:07.000
     2             3            5          2016-08-29 13:37:07.000
     2             4            1          2016-08-29 15:37:07.000
     2             5            10         2016-08-29 15:41:07.000
     3             6            0          2016-08-29 15:41:07.000

我想要的是在表上顯示多少個成功/警告/錯誤,其中以Request_ID中的最新事務的結束時間為單位:

--REQUEST_ID--Transactions----------EndTime----------Success----Warning----Error     
     1               2        2016-08-29 12:37:07.000   50         50         0
     2               3        2016-08-29 15:41:07.000    0         33         66
     3               1        2016-08-29 15:41:07.000   100         0         0

我有下面的slq想要的表,但是我不知道如何在linq(C#)中做到這一點。

SELECT distinct t1.[REQUEST_ID], 
              t2.Transactions,
              t2.EndTime,
              t2.Success,
              t2.Warning,
              t2.Error
          FROM [dbo].[jp_R_ITEM] t1 inner join(
          select top(100) max([EXECUTION_DTTM]) EndTime,  REQUEST_ID,
                 count([ITEM_ID]) as Transactions,
                 coalesce(count(case when [ITEM_STATUS_CD] = 0 then 1 end), 0) * 100 / count([ITEM_ID]) as Success,
                 coalesce(count(case when [ITEM_STATUS_CD] = 1 then 1 end), 0) * 100 / count([ITEM_ID]) as Warning,
                 coalesce(count(case when [ITEM_STATUS_CD] > 1 then 1 end), 0) * 100 / count([ITEM_ID]) as Error
            from  [dbo].[jp_R_ITEM] group by REQUEST_ID order by REQUEST_ID desc) t2 on t1.[REQUEST_ID] = t2.REQUEST_ID and t1.[EXECUTION_DTTM] = t2.EndTime
var query = (from t1 in lst
                     join t2 in (from b in lst
                                 group b by b.REQUEST_ID into grp
                                 select new
                                 {
                                     EndTime = (from g1 in grp select g1.EXECUTION_DTTM).Max(),
                                     REQUEST_ID = grp.Key,
                                     Transactions = grp.Count(),
                                     Success = ((from g2 in grp select g2.ITEM_STATUS_CD).Count(x => x == 0)) * 100 / grp.Count(),
                                     Warning = ((from g3 in grp select g3.ITEM_STATUS_CD).Count(x => x == 1)) * 100 / grp.Count(),
                                     Error = ((from g4 in grp select g4.ITEM_STATUS_CD).Count(x => x > 1)) * 100 / grp.Count(),
                                 }).OrderByDescending(x => x.REQUEST_ID).Take(100)
                     on new { RID = t1.REQUEST_ID, EXDT = t1.EXECUTION_DTTM } equals new { RID = t2.REQUEST_ID, EXDT = t2.EndTime }
                     select new
                     {
                         t1.REQUEST_ID,
                         t2.Transactions,
                         t2.EndTime,
                         t2.Success,
                         t2.Warning,
                         t2.Error
                     }).Distinct().ToList();

因此,從您所有帶有RequestId 1的Transactions ,您想要一個元素。 這個元素應該具有RequestId ,在這種情況下為1,它應該具有所有帶有RequestId ExecutionDttms或事務的最新值,最后,從所有這些事務中,您都希望獲得一定百分比的成功,警告和錯誤

對於具有RequestId 2的事務和具有RequestId 3的事務,您需要類似的內容。

每當您看到類似“我想將一個序列中的所有項目分組為一個對象”這樣的內容時,您都應該立即想到GroupBy。

這個對象可能是一個非常復雜的對象,一個List,一個Dictionary或具有很多屬性的類的一個對象

因此,讓我們首先創建具有相同RequestId的事務組:

var groupsWithSameRequestId = Transactions
    .GroupBy(transaction => transaction.RequestId);

每個組都有一個Key ,它是Group中所有元素的RequestId 每個組都是 (沒有)具有此RequestId值的所有事務的序列。

您想將每個組轉換為一個結果元素。 每個結果元素都有一個屬性RequestId和具有此RequestId的事務數。

RequestId是該組的KeyTransactionCount當然是該組中的元素數

var result = groupsWithSameRequestId.Select(group => new
{
    RequestId = group.Key,
    TransactionCount = group.Count(),
    ...
};

那些是最簡單的。

結束時間是組中所有ExecutionDttm的最大值。

 var result = groupsWithSameRequestId.Select(group => new
{
    RequestId = group.Key,
    TransactionCount = group.Count(),
    EndTime = group.Select(groupElement => groupElement.ExecutionDttm).Max(),
    ...
};

可能是您的數據查詢翻譯器不允許Datetime上的Max。 在這種情況下:降序排列並采用第一個:

EndTime = group.Select(groupElement => groupElement.ExecutionDttm)
    .OrderByDescenting(date => date)
    .First(),

First()足夠, FirstOrDefault() ,我們知道沒有任何元素的組

我們將最后一個最困難/最有趣的部分保存了下來。 您需要成功/警告/錯誤的百分比,這是ItemStatus 0/1 /更多的元素數。

Success = 100 * group
    .Where(groupElement => groupElement.ItemStatus == 0).Count()
    /group.Count(),
Warning = 100 * group
    .Where(groupElement => groupElement.ItemStatus == 1).Count()
    /group.Count(),
Error = 100 * group
    .Where(groupElement => groupElement.ItemStatus > 1).Count()
    /group.Count(),

這取決於您的IQueryable / DbContext有多聰明。 但是乍一看,似乎經常調用Count()。 引入額外的Select可以防止這種情況。

因此,將所有這些組合成一個LINQ語句:

var result = Transactions
    .GroupBy(transaction => transaction.RequestId)
    .Select(group => new
    {
        RequestId = group.Key
        GroupCount = group.Count(),
        SuccessCount = group
            .Where(groupElement => groupElement.ItemStatus == 0).Count(),
        WarningCount = group
            .Where(groupElement => groupElement.ItemStatus == 1).Count(),
        ErrorCount = group
            .Where(groupElement => groupElement.ItemStatus > 1).Count(),

        EndTime = group
            .Select(groupElement => groupElement.ExecutionDttm)
            .Max(),
     })
     .Select(item => new
     {
         RequestId = item.RequestId,
         TransactionCount = item.GroupCount,

         EndTime = item.EndTime,

         SuccessCount = 100.0 * item.SuccesCount / item.GroupCount,
         WarningCount = 100.0 * item.WarningCount / item.GroupCount,
         ErrorCount = 100.0 * item.ErrorCount / item.GroupCount,
     }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM