【问题标题】:Using NHibernate to select entities based on activity of children entities使用 NHibernate 根据子实体的活动选择实体
【发布时间】:2010-04-19 19:33:39
【问题描述】:

我有一个星期一的案子......

我需要根据帖子的 cmets 集合中的最近活动选择博客帖子(帖子具有 List<Comment> 属性,同样,评论具有帖子属性,建立关系。我不想显示相同的发了两次,我只需要实体的一个子集,而不是所有的帖子。

首先想到的是抓取所有包含 cmets 的帖子,然后根据最新评论对这些帖子进行排序。为此,我很确定我必须将每个帖子的 cmets 限制为第一个/最新的评论。最后,我只需选择前 5 个(或我想传递给方法的任何最大结果数)。

第二个想法是抓取由 CreatedOn 排序的所有 cmets,然后过滤,以便每个帖子只有一个评论。然后返回那些顶部(无论如何)帖子。这似乎和第一个选项一样,只是通过后门。

我有一个丑陋的两个查询选项,我在旁边使用了一些 LINQ 进行过滤,但我知道使用 NHibernate API 有一种更优雅的方法。希望在这里看到一些好的想法。

编辑:到目前为止,这对我有用。虽然它有效,但我确信有更好的方法来做到这一点......

// get all comments ordered by CreatedOn date
var comments = Session.CreateCriteria(typeof(Comment)).AddOrder(new Order("CreatedOn", false)).List<Comment>();
var postIDs = (from c in comments select c.ParentPost.ID).Distinct();

// filter the comments
List<Post> posts = new List<Post>();
foreach(var postID in postIDs)
{
    var post = Get(postID); // get a Post by ID
    if(!posts.Contains(post)) // this "if" is redundant due to the Distinct filter on the PostIDs collection
    {
        posts.Add(post);
    }
}

return posts;

【问题讨论】:

    标签: c# sql nhibernate


    【解决方案1】:

    这是使用 NHibernate.LambdaExtensions 语法,但应该很容易转换为标准条件查询或 hql 查询。

    var query1 = DetachedCriteria.For<Post>()
        .CreateCriteria<Post>(x => x.Comments)
        .Add<Comment>(x => x.CreatedDate >= DateTime.Now.AddDays(-5));
    
    query1.GetExecutableCriteria(session).List<T>();
    

    您可能还想急切地加载集合并将您的限制设置为适用于您希望避免拉回整个数据库以及遍历延迟加载列表的 N+1 查询条件。

    使用 NHibernate 解决任何类型的复杂查询的第一步是从原始 SQL 开始,所以我们真的需要从类似的东西开始

    Select P.*
    From Post P
    Where P.PostID Exists (
        Select P1.PostID
        From Posts P1 Inner Join Comments C ON ( P1.PostID = C.PostID )
        Where P1.PostID Exists (
            Select Top 5 C1.PostID, Count(*) as PostCount 
            From Comments C1
            Group By C1.PostID
            Order By PostCount DESC
        )
        And C.CreateDate > Now - 5 days
    )
    

    这是手写的,因此这更像是查询的近似值,应该能够为您指明能够解决查询的方向。通过对此的一些反馈,我可以添加更多关于将其翻译为 NH 的内容。此外,最后一个外部存在可能会在最终的 NH 版本中被删除,因为我相信 Post with Comments 矩阵是 NH 将如何急切地加载实体。

    【讨论】:

    • 这是一个开始,但我不想只发布过去 5 天的 cmets 帖子。我需要所有帖子的前 5 个结果,其中 cmets 按他们最近的评论排序。目标应用程序没有获得大量流量,因此如果在 x 时间内没有活动,则根本不会显示任何帖子。
    • 你到底是什么意思?拥有最新 cmets 的帖子?
    • 是的,我只需要 5 个独特的帖子,但选择哪 5 个是基于他们最新评论的年龄。所以,我试图获取每个帖子的最新评论,然后根据帖子评论的日期对帖子进行排序(假设我们只是查看帖子的单个最新评论),然后取前 5 个帖子。我知道如何获得我需要的有限结果集。我正在努力研究如何根据每个帖子最新评论的年龄优雅地选择一组帖子。
    • 您的解决方案开始朝这个方向发展,但只查看过去 5 天制作的 cmets。我需要按照从最新到最旧的方向应用到所有 cmets 的排序。
    • 只是提醒一下,我在原始问题中放弃了一个我现在如何做的例子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 1970-01-01
    相关资源
    最近更新 更多