为了使用组简单的LINQ查询返回一个一对多的关系 [英] Simple linq query using group in order to return a one to many relationship

查看:171
本文介绍了为了使用组简单的LINQ查询返回一个一对多的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有用户数据表和user_ratings的另一个表。这是一个一对多的关系使他们由用户ID ,用户表作为主键和具有外键关系的user_ratings加盟。每个user_ratings有一列称为RATING_VALUE及其填充有一个int,负的或正的,并且它被加在一起以计算作为用户的评级。我希望能够拉动收视率取决于日期定等级每个用户。以下是我迄今为止我的LINQ语句,但我不认为这是正确的。

I have a data table of users and another table of user_ratings. It is a one to many relationship so the they are joined by UserId, the users table being the primary key and the user_ratings having the foreign key relationship. Each user_ratings has a column called rating_value and its filled with an int, negative or positive, and it gets summed together to be calculated as the user's rating. I want to be able to pull ratings for each user depending on the date for given ratings. Here is what I have so far with my linq statement, but I don't think it is right.

var profiles = from userprofs in Ent.UserProfiles
               join userratings in Ent.UserRatings on userprofs.UserId equals userratings.UserId
               where userratings.DateAdded >= drm.Start
               group userprofs by userprofs.UserId into g
               select new { ... };

不是真的知道从哪里何去何从,我不知道如果我正确地使用该组。我希望能够通过这个集合迭代以后能够显示基于user_ratings总和的每个用户和他或她相关联的评价

Not really sure where to go from here, I'm not sure if I'm using the group correctly. I want to be able to iterate through this collection later to be able to display each user and his or her associated rating based of the sum of the user_ratings

推荐答案

如果你想知道关于收视率的信息是信息汇总(求和,平均值,计数等),那么你可以做这样的事:

If all the information you wish to know about the ratings is aggregate information (sum, average, count, etc) then you can do the likes of this:

var profiles = from userprof in Ent.UserProfiles
  join userrating in Ent.UserRatings on userprofs.UserId equals userratings.UserId
  where userrating.DateAdded >= drm.Start
  group userrating by userprof into g
  select new {g.Key.UserID, g.Key.UserName, Count = g.Count(), Avg = g.Avg(r => r.RatingValue) };

请注意,我改变了复数奇异的名字,因为我们在每一个单独的项目来定义LINQ查询(是的UserProfiles多元,而userprof中的每一个项目的话)。

Note that I changed the plurals to singular names, since we define linq queries in terms of each individual item (UserProfiles is plural, and userprof each item "in" it).

这有一个很好的直接的转化为SQL:

This has a nice straight-forward conversion to SQL:

SELECT up.userID, up.userName, COUNT(ur.*), AVG(ur.ratingValue)
FROM UserProfiles up JOIN UserRatings ur
ON up.userID = ur.userID
WHERE dateAdded > {whatever drm.Start is}
GROUP BY up.userID, up.userName

如果我们希望能够进入个人收视率,这不符合单个SQL查询匹配太好了,我们可以这样做:

If we want to be able to get into individual ratings, this does not match too well with a single SQL query, we could do:

var profiles = from userprof in Ent.UserProfiles
  join userrating in Ent.UserRatings on userprofs.UserId equals userratings.UserId
  where userrating.DateAdded >= drm.Start
  group new{userrating.RatingValue, userrating.SomeThing} by new{userprof.UserID, userprof.UserName};

这会给我们一个的IEnumerable<分组< {匿名对象},{匿名对象}>> ,我们可以遍历,得到一个新的 Key.UserID Key.UserName 在每次迭代,并能够通过遍历反过来越来越 item.RatingValue item.SomeThing (我添加在演示中,如果我们想只值这将是一个的IEnumerable<组合< {匿名对象},诠释>> )是这样的:

This would give us an IEnumerable<Grouping<{anonymous object}, {anonymous object}>> that we could iterate through, getting a new Key.UserID and Key.UserName on each iteration, and being able to iterate through that in turn getting item.RatingValue and item.SomeThing (that I added in for demonstration, if we want just the value it would be an IEnumerable<Grouping<{anonymous object}, int>>) like this:

foreach(var group in profiles)
{
  Console.WriteLine("The user is :" + group.Key.UserName + " (id: " + group.Key.UserID ")");
  foreach(var item in group)
  {
    Console.WriteLine(item.SomeThing + " was rated " + item.RatingValue);
  }
}

然而,这样做的问题是,没有一个很好的单个SQL查询,这映射到。 LINQ将竭尽所能,但是这将意味着执行多个查询,所以你最好还是帮它:

However, the problem with this, is that there isn't a nice single SQL query that this maps to. Linq will do its best, but that'll mean executing several queries, so you're better off helping it out:

var profiles = from item in (from userprof in Ent.UserProfiles
  join userrating in Ent.UserRatings on userprofs.UserId equals userratings.UserId
  where userrating.DateAdded >= drm.Start
  select new{userrating.RatingValue, userrating.SomeThing, userprof.UserID, userprof.UserName}).AsEnumerable()
  group new{item.RatingValue, item.SomeThing} by new{item.UserID, item.UserName}

此作为前具有相同的输出,但翻译成SQL允许对要由单一的查询,与工件的其余部分在存储器正在做。的99%的时间,拖了一些工作到这样的内存使得事情效率较低,但由于previous没有一个单一的SQL查询它可以映射到,这是一个例外。

This has the same output as before, but the translation into SQL allows for a single query to be made, with the rest of the work being done in memory. 99% of the time, dragging some work into memory like this makes things less efficient, but because the previous doesn't have a single SQL query it can map to, it's an exception.

这篇关于为了使用组简单的LINQ查询返回一个一对多的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆