使用Entity Framework 6进行Distinct筛选的查询

5

I have a problem. When I run the code below:

var data = context.TableX.Where(w => w.userId == 9999&& w.id == 9999) .Distinct().ToList();

这是生成的查询:

SELECT [Extent1].[id] AS [id], [Extent1].[name] AS [name], [Extent1].[companyId] AS [companyId], [Extent1].[userId] AS [userId] FROM [TableX] AS [Extent1] WHERE (9999 = [Extent1].[userId]) AND (9999= [Extent1].[id]) -- Executing at 01/06/2016 17:28:01 -03:00 -- Completed in 271 ms with result: SqlDataReader

我想知道您是否能使“Distinct”与以下查询一起运行:
SELECT DISTINCT id, name, companyId AS type FROM TableX WHERE id=9999 AND userId=9999

感谢您的选择。

1
id 是唯一的吗?(通常应该是)因为如果是,那么所有结果都将具有不同的特点,无论是否使用 DISTINCT 关键字。也许 EF 正在识别并且不使用它。 - Andy Nichols
你的表中是否有多条userid = 9999和id = 9999的记录?在SQL中,Distinct关键字通常具有计算成本。如果没有多个匹配记录,linq的版本可能更好,即使有多个返回值,我也希望它在客户端执行distinct。 - Travis
ID不是唯一的,这就是为什么我需要在查询中使用“DISTINCT”的原因。 - Will
即使ID不是唯一的,如果您正在使用Code First,EF可能会认为它是唯一的。从https://msdn.microsoft.com/en-gb/data/jj679962.aspx“Code First推断,如果类上的属性命名为“ID”(不区分大小写)或类名后跟“ID”,则该属性是主键。如果主键属性的类型为数字或GUID,则将其配置为标识列。” - Andy Nichols
1个回答

6
为了获得所需的查询结果,您需要先调用Select,然后再调用Distinct,以获取只需应用不同的列:
var data = context.TableX.Where(w => w.userId == 9999&& w.id == 9999)
                         .Select(e=>new {e.id, e.name, e.companyId}) 
                         .Distinct()
                         .ToList();

更新1

我相信第一个查询应该可以工作,但是另一种解决方案可能是应用group by:

var data = context.TableX.Where(w => w.userId == 9999&& w.id == 9999)
                         .GroupBy(e=>new {e.id, e.name, e.companyId}) 
                         .Select(g=>new{g.Key.id, g.Key.name, g.Key.companyId})
                         .ToList();

更新2

现在我在另一个上下文中使用相同的思路在LinqPad中测试了第一个查询:

var query=Agencies.Where(a=>a.StatusId==1)
                  .Select(e=>new{e.StateId, e.AgencyName})
                  .Distinct()
                  .Dump();

以下是生成的 SQL 语句:

-- Region Parameters
DECLARE @p0 Int = 1
-- EndRegion
SELECT DISTINCT [t0].[stateId] AS [StateId], [t0].[agencyName] AS [AgencyName]
FROM [Agencies] AS [t0]
WHERE [t0].[statusId] = @p0

从您看到的情况来看,它应该可以工作,但我不知道在您的情况下发生了什么。

对于通过LinqPad执行的第二个查询,重复相同的过程:

var query=Agencies.Where(a=>a.StatusId==1)
                  .GroupBy(e=>new{e.StateId, e.AgencyName})
                  .Select(g=>new{g.Key.StateId, g.Key.AgencyName})
                  .Dump();

这是 SQL 代码:

-- Region Parameters

DECLARE @p0 Int = 1
-- EndRegion
SELECT [t0].[stateId] AS [StateId], [t0].[agencyName] AS [AgencyName]
FROM [Agencies] AS [t0]
WHERE [t0].[statusId] = @p0
GROUP BY [t0].[stateId], [t0].[agencyName]

这很奇怪,而且“where”在哪里?真的,这没有意义。你确定是同一个查询吗? - ocuenca
抱歉,我忘记了where子句:SELECT [Extent1].[id] AS [id], [Extent1].[name] AS [name], [Extent1].[companyId] AS [companyId] FROM TableX AS [Extent1] WHERE (5093 = [Extent1].[userId]) AND (2698 = [Extent1].[id]) - Will
最大的问题是distinct没有运行。它返回了六条完全相同的记录,而在数据库中使用distinct只返回1条。 - Will
我不明白为什么会忽略“Distinct”,它应该可以工作。请尝试第二个查询。 - ocuenca
Octavio,我运行了这段代码:var data = context.TabelaX.Where(w => w.userId == 5093 && w.id == 2698).Select(e => new { e.id }).Distinct().ToList();结果是:SELECT [Distinct1].[C1] AS [C1], [Distinct1].[user_id] AS [user_id] FROM ( SELECT DISTINCT [Extent1].[usuarios_id] AS [usuarios_id], 1 AS [C1] FROM TabelaX AS [Extent1] WHERE (5093 = [Extent1].[userId]) AND (2698 = [Extent1].[id]) ) AS [Distinct1] - Will
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接