C#SQL to Linq - 翻译

时间:2018-05-23 08:28:43

标签: c# linq

我有一个包含交易的表,类似于:

--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

2 个答案:

答案 0 :(得分:0)

map.merge("car", 100, Integer::sum);
map.merge("car", 20, Integer::sum);

System.out.println(map); // {car=120}

答案 1 :(得分:0)

所以Transactions所有RequestId 1,你想要制作一个元素。这个元素应该有RequestId,在这种情况下是1,它应该具有所有ExecutionDttms的最新值或具有RequestId的事务,最后,来自您想要的所有交易一定比例的成功,警告和错误

对于使用RequestId 2的交易,以及使用RequestId 3的交易等,您需要类似的东西。

  

每当你看到类似于:"我想将序列中的所有项目分组到一个对象中时#34;你应该立即想到GroupBy。

这个对象可能是一个非常复杂的对象,一个List,一个Dictionary或一个具有很多属性的类的对象

因此,让我们首先制作具有相同RequestId的交易组:

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

每个群组都有Key,这是群组中所有元素的RequestId。每个 <(不)拥有此RequestId值的所有Transaction的序列。

您希望将每个组转换为一个结果元素。每个结果元素 有一个属性RequestId以及包含此RequestId的交易数。

RequestId是群组的KeyTransactionCount当然是群组中的元素数量

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

那是最容易的。

Endtime是组中所有ExecutionDttm的最大值。

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

可能是您的数据查询转换器不允许Max on Datetime。在这种情况下:顺序下降并采取第一个:

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,
     }