我有一个用户数据表和另一个user_ratings表。它是一对多关系,因此它们由UserId
连接,用户表是主键,user_ratings具有外键关系。每个user_ratings都有一个名为rating_value的列,其中填充了一个int,negative或positive,并将它们汇总在一起计算为用户的评级。我希望能够根据给定评级的日期为每个用户提取评级。这是我到目前为止我的linq声明,但我不认为这是正确的。
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的总和显示每个用户及其相关评级
答案 0 :(得分:2)
如果您希望了解有关评级的所有信息是汇总信息(总和,平均值,计数等),那么您可以执行以下操作:
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每个项目都在“in”中)。
这对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查询不太匹配,我们可以这样做:
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<Grouping<{anonymous object}, {anonymous object}>>
我们可以迭代,在每次迭代时获得一个新的Key.UserID
和Key.UserName
,并且能够反过来获得{{1} }}和item.RatingValue
(我为了演示而加入了,如果我们只想要一个item.SomeThing
的值),就像这样:
IEnumerable<Grouping<{anonymous object}, int>>
然而,问题是,这个映射到的单个SQL查询不是很好。 Linq会尽力而为,但这意味着执行几个查询,所以你最好帮忙解决:
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允许进行单个查询,其余工作在内存中完成。 99%的时间,将一些工作拖入内存这样会降低效率,但由于之前没有一个可以映射到的SQL查询,这是一个例外。
答案 1 :(得分:0)
如果我理解你的问题:
from userprofs in Ent.UserProfiles
join userratings in Ent.UserRatings on userprofs.UserId equals userratings.UserId
where userratings.DateAdded >= drm.Start
group new{userprofs,userratings} by userprofs.UserId into g
select new { userId=g.Key, userRating=g.Sum(i=>i.userratings.rating_value) };
GroupBy
会返回IEnumerable
IGrouping
。 IGrouping
基本上是IEnumerable
,具有额外的Key
属性,其中包含用于进行分组的属性。如果您Sum
分组rating_value
,那么就在那里。