简体   繁体   English

Linq to SQL:选择最新的DISTINCT条目

[英]Linq to SQL: SELECT latest DISTINCT entries

Given a table with the columns: [AuditEntityId] [UserName] [CaseID] 给定一个带有列的表:[AuditEntityId] [UserName] [CaseID]

I want a distinct list of [CaseID]'s for a specific [UserName] that has the highest [AuditEntityId]. 我想要具有最高[AuditEntityId]的特定[UserName]的[CaseID]的不同列表。

Basically, I want the last five cases that a user worked on, in the order from latest to oldest. 基本上,我希望用户按照从最新到最早的顺序处理用户的最后五个案例。

I am achieving the distinct by grouping on [CaseID]: 我通过对[CaseID]进行分组来实现与众不同:

var lastItems = baseController.db.AuditEntities
                                 .OrderByDescending(a => a.AuditEntityId)
                                 .GroupBy(a => a.CaseID)
                                 .Select(a => a.FirstOrDefault())
                                 .Where(a => a.CaseID != null && a.CaseID != 0)
                                 .Where(a => a.UserName == filterContext.HttpContext.User.Identity.Name)
                                 .Take(5)
                                 .ToList();

This achieves the goal of giving me a distinct list of cases a user worked on, but the .OrderByDescending is totally ignored. 这实现了为我提供用户处理过的不同案例列表的目标,但是.OrderByDescending被完全忽略了。 The top linq statement is transformed into the following SQL: 顶部linq语句转换为以下SQL:

SELECT TOP (5)
    [Limit1].[AuditEntityId] AS [AuditEntityId],
    [Limit1].[Reference] AS [Reference],
    [Limit1].[Timestamp] AS [Timestamp],
    [Limit1].[EntityName] AS [EntityName],
    [Limit1].[UserName] AS [UserName],
    [Limit1].[Action] AS [Action],
    [Limit1].[ComplaintId] AS [ComplaintId],
    [Limit1].[CaseID] AS [CaseID],
    [Limit1].[AuditReferencingStart] AS [AuditReferencingStart],
    [Limit1].[AuditReferencingEnd] AS [AuditReferencingEnd]
FROM
    (SELECT DISTINCT
        [Extent1].[CaseID] AS [CaseID]
    FROM
        [dbo].[AuditEntity] AS [Extent1] ) AS [Distinct1]
    CROSS APPLY (SELECT TOP (1)
        [Extent2].[AuditEntityId] AS [AuditEntityId],
        [Extent2].[Reference] AS [Reference],
        [Extent2].[Timestamp] AS [Timestamp],
        [Extent2].[EntityName] AS [EntityName],
        [Extent2].[UserName] AS [UserName],
        [Extent2].[Action] AS [Action],
        [Extent2].[ComplaintId] AS [ComplaintId],
        [Extent2].[CaseID] AS [CaseID],
        [Extent2].[AuditReferencingStart] AS [AuditReferencingStart],
        [Extent2].[AuditReferencingEnd] AS [AuditReferencingEnd]
    FROM
        [dbo].[AuditEntity] AS [Extent2]
    WHERE
        ([Distinct1].[CaseID] = [Extent2].[CaseID]) OR (([Distinct1].[CaseID] IS NULL) AND ([Extent2].[CaseID] IS NULL)) ) AS [Limit1]
WHERE
    ([Limit1].[CaseID] IS NOT NULL) AND ( NOT ((0 = [Limit1].[CaseID]) AND ([Limit1].[CaseID] IS NOT NULL))) AND (([Limit1].[UserName] = @p__linq__0))

The provided SQL does not have a ORDER in it at all. 提供的SQL根本没有ORDER。 I can move the .OrderByDescending to after the .GroupBy(a => a.CaseID).Select(a => a.FirstOrDefault()) , but then it orders the result after the TOP (1) has been SELECT ed, which doesn't give me the latest audit entries. 我可以将.OrderByDescending移到.GroupBy(a => a.CaseID).Select(a => a.FirstOrDefault()) ,但是在对TOP (1)进行SELECT .GroupBy(a => a.CaseID).Select(a => a.FirstOrDefault())之后,它对结果进行.GroupBy(a => a.CaseID).Select(a => a.FirstOrDefault())没有给我最新的审核条目。

I also tried making use of MoreLinq 's .DistinctBy , but with this the .OrderByDescending still does not work as intended: 我还尝试使用MoreLinq.DistinctBy ,但是.OrderByDescending仍然无法按预期工作:

var lastItems = baseController.db.AuditEntities
                                 .Where(a => a.CaseID != null && a.CaseID != 0 && a.UserName == filterContext.HttpContext.User.Identity.Name)
                                 .DistinctBy(a => a.CaseID)
                                 .OrderBy(a => a.AuditEntityId)
                                 .Take(5)
                                 .ToList();

You need to order your result set. 您需要订购结果集。 Try 尝试

var lastItems = baseController.db.AuditEntities                                 
                             .GroupBy(a => a.CaseID)
                             .Select(a => a.FirstOrDefault())
                             .Where(a => a.CaseID != null && a.CaseID != 0)
                             .Where(a => a.UserName == filterContext.HttpContext.User.Identity.Name)
                             .OrderByDescending(a => a.AuditEntityId)
                             .Take(5)
                             .ToList();

When you Group By CaseID after Order By AuditEntityId , followed by other operations, that order OrderBy does not have an effect on the result set. Group By CaseIDOrder By AuditEntityId ,其次是其他操作,依次OrderBy不会对结果集的效果。

Edit 编辑

Without knowing the exact schema, I can't be certain. 不知道确切的架构,我无法确定。 But going by "I want a distinct list of [CaseID]'s for a specific [UserName] that has the highest [AuditEntityId]" , you can try this 但是通过“我想要具有最高[AuditEntityId]的特定[UserName]的[CaseID]的不同列表” ,您可以尝试执行此操作

.db.AuditEntities
    .Where(a => a.CaseID != null 
                && a.CaseID != 0
                && a.UserName == filterContext.HttpContext.User.Identity.Name)
    .GroupBy(a => a.CaseID)
    .OrderByDescending(grp => grp.Max(g => g.AuditEntityId))        
    .Take(5)
    .Select(a => a.FirstOrDefault())
    .ToList();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM