LINQ to NHibernate join - 查询每个组的最新 N 个 - 不支持异常



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

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; }
...
}

有人可以解释一下我的查询有什么问题以及为什么我会收到此错误吗?

NHibernate不支持子查询上的联接。这给了你NotSupportedException.

它在逐个子查询方面也存在一些问题(有关详细信息,请参阅如何在 NHibernate 中查询每个组中的第一个条目(。但是使用此答案中描述的最后一个技术,您可以将查询重写为如下所示的内容:

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

我假设通信就像多个消息的线程,并且CustomerId存在于通信级别,然后消息具有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 的帖子(这将选择所有最新的每次通信消息。也许然后爬行对象树会像m.First().Communication.Customer.Name

即希望您可以从这些中加入/导航到通信,获得客户等。我对原始查询 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

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

也许这就是你想做的?

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

最新更新