TSQL Distinct唯一结果集是必需的,但我得到了重复的值

本文关键字:结果 唯一 TSQL Distinct | 更新日期: 2023-09-27 18:28:20

由于一些奇怪的原因,下面的代码为表中的每一行都提供了一个值。我只想要独特的价值观:

public IQueryable<WasteIndicatorItem> FindAllEWC()
{
    var results = (from x in this._db.WasteIndicatorItems
                   orderby x.EWC
                   select x).ToList();

    return results.OrderBy(s => s.EWC).Distinct().AsQueryable();
}

在ToList ETC之前,我试着把.Dispinct()移得到处都是。我做错了什么,一定很简单,为阅读欢呼。。

因此,在我的结果中,我得到:

13
13
13
12345
12345

而不是:

13
12345

表结构为:

CREATE TABLE [dbo].[WasteIndicatorItem](
    [WasteIndicatorItemId] [int] IDENTITY(1,1) NOT NULL,
    [WasteId] [int] NOT NULL,
    [WasteIndicatorId] [int] NOT NULL,
    [EWC] [varchar](6) COLLATE Latin1_General_CI_AS NOT NULL,
    [WasteHazardCodeId] [int] NOT NULL,
    [Quantity] [money] NOT NULL,
    [Notes] [varchar](4000) COLLATE Latin1_General_CI_AS NULL,
    [EnteredById] [int] NOT NULL,
    [Entered] [datetime] NOT NULL,
    [LastModifiedById] [int] NULL,
    [LastModified] [datetime] NULL,
 CONSTRAINT [PK_IndicatorItem] PRIMARY KEY CLUSTERED 
(
    [WasteIndicatorItemId] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

TSQL Distinct唯一结果集是必需的,但我得到了重复的值

您正在将Distinct应用于List,而不是EF DBSet。确保列表中的每个条目都是唯一的,除非您定义了IEquatable实现。因此,如果您想在客户端丢弃重复项,您必须为数据对象实现IEquatable,或者您可以在查询中使用分组。

Linq Distinct()的行为并不像您所期望的那样。

您需要创建一个相等比较器,并在Union或Distinct(请参阅此处)中使用它

或者可以尝试MoreLinq库中的DistinctBy

您有两个选择:

  1. 使用GroupBy并将所有内容都保留在SQL端(首选)。你会根据你感兴趣的属性进行分组,这些属性定义了你的独特性
  2. 使用AsEnumerable来关闭所有内容,然后使用接受IEqualityComparer的重载Distinct方法。这通常不是一个好主意(除非结果集很小),因为所有匹配的结果都会被返回,并且在SQL端完成的处理更少

实现第一个解决方案如下:

var results = _db.WasteIndicatorItems
                 .OrderBy(x => x.EWC)
                 .GroupBy(x => x.EWC)
                 .Select(x => x.First());

您希望项目在什么方面不同?默认情况下,假设您将Distinct()调用放在具体化结果之前,并使用ToList()移回Linq到Objects,我假设实体框架将查看作为主键的WasteIndicatorItemId,并且根据定义将是唯一的,因此Distinct调用不会更改任何内容(甚至可能被优化掉)。