C# LINQ-如何将distinct与order by一起使用?

C# LINQ-如何将distinct与order by一起使用?,c#,sql,.net,linq,nhibernate,C#,Sql,.net,Linq,Nhibernate,我想在这方面做一个明确的说明: query = from acao in query join itemAuditoria in Session.Query<ItemAuditoria>() on acao.Id equals itemAuditoria.Acao.Id join auditoria in Session.Query<Auditoria>() on itemAuditoria.Auditoria.Id equals auditoria.Id j

我想在这方面做一个明确的说明:

query = from acao in query
  join itemAuditoria in Session.Query<ItemAuditoria>() on acao.Id equals itemAuditoria.Acao.Id
  join auditoria in Session.Query<Auditoria>() on itemAuditoria.Auditoria.Id equals auditoria.Id
  join maquina in Session.Query<Maquina>() on auditoria.Maquina.Id equals maquina.Id
  orderby maquina.Nome, acao.Numero
  select acao;
query=来自查询中的acao
在acao.Id上的Session.Query()中加入itemAuditoria等于itemAuditoria.acao.Id
在itemAuditoria.auditoria.Id上的Session.Query()中加入auditoria等于auditoria.Id
在auditoria.maquina.Id等于maquina.Id的Session.Query()中加入maquina
订单由maquina、Nome、acao、Numero订购
选择acao;
但是如果我尝试在查询的末尾添加一个distinct,如下所示:

query = (from acao in query
  join itemAuditoria in Session.Query<ItemAuditoria>() on acao.Id equals itemAuditoria.Acao.Id
  join auditoria in Session.Query<Auditoria>() on itemAuditoria.Auditoria.Id equals auditoria.Id
  join maquina in Session.Query<Maquina>() on auditoria.Maquina.Id equals maquina.Id
  orderby maquina.Nome, acao.Numero
  select acao).Distinct();
query=(来自查询中的acao)
在acao.Id上的Session.Query()中加入itemAuditoria等于itemAuditoria.acao.Id
在itemAuditoria.auditoria.Id上的Session.Query()中加入auditoria等于auditoria.Id
在auditoria.maquina.Id等于maquina.Id的Session.Query()中加入maquina
订单由maquina、Nome、acao、Numero订购
选择acao).Distinct();
然后我得到这个错误:

如果指定了select DISTINCT,则ORDER BY项目必须出现在选择列表中


与OP评论中的答案相比,不确定对性能的影响,但为了可读性,可以对其进行子查询

query =
    (from distinctAcao in
        (from acao in query
        join itemAuditoria in Session.Query<ItemAuditoria>() on acao.Id equals itemAuditoria.Acao.Id
        join auditoria in Session.Query<Auditoria>() on itemAuditoria.Auditoria.Id equals auditoria.Id
        join maquina in Session.Query<Maquina>() on auditoria.Maquina.Id equals maquina.Id
        select acao).Distinct()
    orderby maquina.Nome, distinctAcao.Numero
    select distinctAcao);
结果:已排序,唯一
acao
s列表

缺点:先排序,然后过滤可能会影响性能

  • 从子查询返回一个更好的组合对象,它将从联接表中公开新字段

    query2=(
        from distinctMix in (
            from acao in query
            join itemAuditoria in Session.Query<ItemAuditoria>() on acao.Id equals itemAuditoria.Acao.Id
            join auditoria in Session.Query<Auditoria>() on itemAuditoria.Auditoria.Id equals auditoria.Id
            join maquina in Session.Query<Maquina>() on auditoria.Maquina.Id equals maquina.Id
            select new { Id=acao.Id,Numero=acao.Numero,NomeFromMaquina=maquina.Nome }
        ).Distinct()
        orderby distinctMix.NomeFromMaquina,distinctMix.Numero
        select distinctMix
    );
    
    query2=(
    从中的distinctMix(
    来自acao的查询
    在acao.Id上的Session.Query()中加入itemAuditoria等于itemAuditoria.acao.Id
    
    在会话中加入auditoria。查询:>

    正如错误所述:
    如果指定了select DISTINCT,则ORDER BY items必须出现在选择列表中。
    正确,我如何重写此代码以实现这一点?我不能简单地在DISTINCT之后剪切和粘贴ORDER BY。您需要选择对象,然后在发布集合后对其进行排序我不知道我不知道怎么做。告诉我怎么做。@Toons33是的,
    Distinct
    没有等价的查询语法。即使有,这仍然是一个很难解决的问题。你不能将所有内容都转换为方法语法。这并不能解决问题。select必须位于
    Distinct
    或其他仅在c中不同的项之前未投影的列不会被删除,但select需要在
    OrderBy
    之后,因为未投影的列是有序的,
    OrderBy
    需要在
    Distinct
    之前,因为上面的错误消息。这是一个循环依赖关系图。此代码无法编译。我无法在Distinct()之后放置“order by”),编译器抱怨“maquina”(在orderby之后)未被识别。感谢您的努力,但正如我在问题的第二段代码中提到的,如果我在查询中使用order by,则足以在运行时引发异常。它可能在EntityFramework上有效,但我使用的是NHibernate。在您的编辑中,两个解决方案都不起作用。第一个解决方案调用
    Dist在
    OrderBy
    之后执行
    ,然后执行
    Distinct
    对项目进行重新排序。第二个查询不起作用,因为您正在对其他列执行
    Distinct
    ,这意味着只有那些列不同的项目才会在不应该包含的时候被包含。第二个备注我没有意识到;至于第一个Distinct()没有改变我的计算机或在线编译器的顺序,所以我认为它保留了它;因此:这是一次失败的尝试,我为此道歉:C
    query2=(
        from distinctMix in (
            from acao in query
            join itemAuditoria in Session.Query<ItemAuditoria>() on acao.Id equals itemAuditoria.Acao.Id
            join auditoria in Session.Query<Auditoria>() on itemAuditoria.Auditoria.Id equals auditoria.Id
            join maquina in Session.Query<Maquina>() on auditoria.Maquina.Id equals maquina.Id
            select new { Id=acao.Id,Numero=acao.Numero,NomeFromMaquina=maquina.Nome }
        ).Distinct()
        orderby distinctMix.NomeFromMaquina,distinctMix.Numero
        select distinctMix
    );