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

本文关键字:DISTINCT 条目 最新 选择 to SQL Linq | 更新日期: 2023-09-27 18:31:28

给定一个包含以下列的表:[AuditEntityId] [用户名] [CaseID]

我想要具有最高 [AuditEntityId] 的特定 [用户名] 的不同 [案例 ID] 列表。

基本上,我想要用户处理的最后五个案例,按从最新到最旧的顺序排列。

我通过对 [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();

这实现了为我提供用户处理的案例的独特列表的目标,但.OrderByDescending被完全忽略。顶部 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))

提供的 SQL 中根本没有 ORDER。我可以将.OrderByDescending移动到.GroupBy(a => a.CaseID).Select(a => a.FirstOrDefault())之后,但它会在SELECT TOP (1)后对结果进行排序,这不会给我最新的审计条目。

我也尝试使用 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();

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

您需要对结果集进行排序。尝试

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();

如果在 Order By AuditEntityId 之后Group By CaseID,后跟其他操作,则该顺序OrderBy对结果集没有影响。

编辑

不知道确切的模式,我无法确定。但是通过"我想要具有最高[AuditEntityId]的特定[用户名]的[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();