繁体   English   中英

如何使用Linq将两个以上的表分组

[英]How to group more than two tables using Linq

我有三个表(“评分”,“评论”和“用户”)。 一个评分可以有多个评论。 一则留言属于一位使用者。

到目前为止,我有这个运行良好的LINQ语句。

from rating in Ratings
join comment in Comments
on rating.ID equals comment.RatingID
join user in Users
on comment.UserID equals user.ID
select new {rating, comment, user}
.Where(x => x.rating.LocationID == 3);

我该如何分组?

这取决于您要分组的内容。 但是有多种解决方案。

解决方案1:

假设您要按评分分组,则可以执行以下操作:

var query1 = from rating in db.Ratings
                join comment in db.Comments
                    on rating.ID equals comment.RatingID
                join user in db.Users
                    on comment.UserID equals user.ID
                group new { comment, user } by rating into g
                select new { g.Key, l = g.ToList() };

foreach (var row in query1)
{
    // you get rows grouped by rating
    Debug.WriteLine(row.Key.ID); // rating.ID

    // and a list of comments/users per rating
    foreach (var g in row.l)
    {
        Debug.WriteLine(g.comment.ID);
        Debug.WriteLine(g.user.ID);
    }
}

这样,您就可以为每个评分单行。 动态对象g包含每个评分的评论/用户对列表。

解决方案2:

但是,就像提到的@gertarnold一样,读入要分组的对象也更容易。 然后遍历它的属性。 像这样:

var query2 = db.Ratings;

foreach (var rating in query2)
{
    Debug.WriteLine(rating.name);
    foreach (var comment in rating.Comments)
    {
        Debug.WriteLine(comment.name);
        Debug.WriteLine(comment.User.name);
    }
}

这很容易理解。 它具有性能下降的困难,因为它对内部循环中的每个注释执行单独的数据库SELECT -statement。 如果一个评分有很多评论,那么这很慢。 第一个带有分组的示例将所有内容放入一个数据库SELECT语句中,这要快得多。

解决方案3:

并且有一种方法可以同时兼顾两者的优点。 像解决方案2一样进行操作,并在其前面添加一些DataLoadOptions

DataLoadOptions options = new DataLoadOptions();
options.LoadWith<Rating>(rating => rating.Comments);
options.LoadWith<Comment>(comment => comment.User);
db.LoadOptions = options;

这将在单个SELECT中将所有必需的子对象预加载所有等级。 它既快速又易于阅读和理解。

PS:附带说明:表格应以单数命名。 在这种情况下, RatingCommentUser而不是RatingsCommentsUsers

PS2:要在解决方案1中也获得没有注释的评分,则需要将联接转换为外部联接。 像这样:

var query1 = from rating in db.Ratings
        join comment in db.Comments
            on rating.ID equals comment.RatingID into j1
        from comment in j1.DefaultIfEmpty()
        join user in db.Users
            on comment.UserID equals user.ID into j2
        from user in j2.DefaultIfEmpty()                                
        group new { comment, user } by rating into g
        select new { g.Key, l = g.ToList() };

另请参阅: 101个LINQ样本-左外部联接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM