LINQ to NHibernate join - 查询每组最新的 N - NotSupportedException

LINQ to NHibernate join - Query latest N per group - NotSupportedException

我正在尝试获取发送给每个客户的最后一条消息。但是我得到了一个没有任何额外细节的 NotSupportedException。我对 LINQ to NHibernate 的 join 方法不熟悉,因为这是第一次使用它。有人可以解释我的查询有什么问题以及为什么我会收到此错误吗?这是我的查询和错误:

var messages = _session.Query<Communication>();     

return messages.Join(
                _session.Query<Communication>().GroupBy(m => m.Customer),
                x => new { x.Customer, x.Message.CreatedOn },
                g => new { Customer= g.Key, CreatedOn = g.Max(p => p.Message.CreatedOn) },
                (x, g) => x)
                .ToList();

System.NotSupportedException: query ( query ( select_from ( from ( range App.Core.Customer m ) ) ( select m ) ) )

实体:

public class Communication
{
    public Message Message { get; set; }
    public Customer Customer { get; set; }
    ...
}

public class Message
{
    public DateTime CreatedOn { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
    ...
}

我假设 Communication 就像是多个消息的线程,并且 CustomerId 存在于 Communication 级别,然后消息具有 CommunicationId 和 CreatedOn。我不声称能够提供 nHibernate/LINQ 语法,但你也许可以使用原始 SQL:

var m = _session.CreateSQLQuery(@"

  SELECT m.Id, m.CommunicationId, m.CreatedOn, m.<put a list of all other columns in messages here>
  FROM
    (SELECT *, ROW_NUMBER() OVER(PARTITION BY CommunicationId ORDER BY CreatedOn DESC) rown FROM Messages) m 
  WHERE m.rown = 1")
.AddEntity(typeof(Message))
.List<Message>();

您需要填写消息中的 < ... > 和所有其他列。我认为(我只看过网络上关于如何 运行 在 nH 中原始 SQL 的帖子)这将 select 所有最新的每次通信消息..然后可能会爬行围绕对象树就像 m.First().Communication.Customer.Name etc

即希望从这些你可以 join/navigate 进入通信,获得客户等。我对原始查询 nH 了解不够,不知道如何让它形成一个包含通信的对象图,但是你可以使用这个查询:

  SELECT d.*
  FROM
    (SELECT *, ROW_NUMBER() OVER(PARTITION BY c.CustomerId ORDER BY CreatedOn DESC) rown FROM Messages m INNER JOIN Communication c ON m.CommunicationId = c.Id) d 
  WHERE d.rown = 1

获取每个客户的所有最新消息(与每个通信的最新消息略有不同,如果一个客户同时有两个通信),并将其与建议 here 相结合,使结果成为动态的

也许这就是你想要做的?

return _session
          .Query<Communication>()
          .GroupBy(e => e.Customer)
          .Select(g => new {Customer = g.Key, MaxDate = g.Max(r => r.Message.CreatedOn)})
          .ToList()

Can someone please explain what is wrong with my query and why I'm getting this error?

NHibernate 不支持子查询的连接。那给你 NotSupportedException.

分组子查询也有一些问题(详见 )。但是使用此答案中描述的最后一种技术,您可以将查询重写为:

var results = session.Query<Communication>()
        .Where(c => c == session.Query<Communication>()
                            .Where(cs => cs.Customer == c.Customer)
                            .OrderByDescending(cs => cs.Message.CreatedOn)
                            .First()
        ).ToList();