我正在开发一个应用程序,我必须在数据表中存储歌曲的播放历史记录。我有一个名为PlayHistory的表,它有四列。
Id | SoundRecordingId(FK) | UserId(FK) | DateTime
现在我必须实现一个查询,该查询将返回处于趋势阶段的歌曲,即主要播放的歌曲。我在sql server中编写了以下查询,它以某种方式将数据返回到我想要的位置。
select COUNT(*) as High,SoundRecordingId
from PlayHistory
where DateTime >= GETDATE()-30
group by SoundRecordingId
Having COUNT(*) > 1
order by SoundRecordingId desc
它返回了我的数据:
High SoundRecordingId
2 5
2 3
这意味着歌曲与Ids 5和3的播放次数最多,即2 我如何通过cq中的Linq实现这一点。 到目前为止我已经这样做了:
DateTime d = DateTime.Now;
var monthBefore = d.AddMonths(-1);
var list =
_db.PlayHistories
.OrderByDescending(x=>x.SoundRecordingId)
.Where(t => t.DateTime >= monthBefore)
.GroupBy(x=>x.SoundRecordingId)
.Take(20)
.ToList();
它返回整个表的列表,其中包含SoundRecording对象的计数,但我只想计算最重复的记录。 感谢
答案 0 :(得分:2)
我喜欢' linq'语法与SQL
类似var query = from history in _db.PlayHistories
where history.DateTime >= monthBefore
group history by history.SoundRecordingId into historyGroup
where historyGroup.Count() > 1
orderby historyGroup.Key
select new { High = historyGroup.Count(), SoundRecordingId = historyGroup.Key };
var data = query.Take(20).ToList();
答案 1 :(得分:2)
.GroupBy
方法存在重载,可以解决您的问题。
DateTime d = DateTime.Now;
var monthBefore = d.AddMonths(-1);
var list =
_db.PlayHistories
.OrderByDescending(x=>x.SoundRecordingId)
.Where(t => t.DateTime >= monthBefore)
.GroupBy(x=>x.SoundRecordingId, (key,values) => new {SoundRecordingID=key, High=values.count()})
.Take(20)
.ToList();
我只是将结果选择器添加到此处的GroupBy
方法调用中,该调用执行与SQL编写的相同的转换。
有问题的方法重载记录为here
要进一步解决您的问题,您可能需要执行另一个OrderByDescending
以获得受欢迎程度的结果。要匹配SQL语句,您还必须仅过滤计数> 1。
DateTime d = DateTime.Now;
var monthBefore = d.AddMonths(-1);
var list =
_db.PlayHistories
.Where(t => t.DateTime >= monthBefore)
.GroupBy(x=>x.SoundRecordingId, (key,values) => new {SoundRecordingID=key, High=values.count()})
.Where(x=>x.High>1)
.OrderByDescending(x=>x.High)
.ToList();
答案 2 :(得分:0)
你已经完成了。只需按计数排序您的清单并采取第一个:
var max =
_db.PlayHistories
.OrderByDescending(x=>x.SoundRecordingId)
.Where(t => t.DateTime >= monthBefore)
.GroupBy(x=>x.SoundRecordingId)
.OrderByDescending(x => x.Count())
.First();
这为您提供了一个键值对,其中Key
是您的SoundRecordingId
,其值是输入列表中出现的次数。
编辑:要获得具有该金额的所有记录,请选择此选项:
var grouped =
_db.PlayHistories
.OrderByDescending(x => x.SoundRecordingId)
.Where(t => t.DateTime >= monthBefore)
.GroupBy(x => x.SoundRecordingId)
.Select(x => new { Id = x.Key, Count = x.Count() }
.OrderByDescending(x => x.Count)
.ToList();
var maxCount = grouped.First().Count;
var result = grouped.Where(x => x.Count == maxCount);
答案 3 :(得分:0)
这可以通过提供您所要求的内容来解决问题。您在LINQ中的查询,只返回播放计数。
var list = _db.PlayHistories.Where(x => x.DateTimeProp > (DateTime.Now).AddMonths(-1))
.OrderByDescending(y => y.SoundRecordingId.Count())
.ThenBy(z => z.SoundRecordingId)
.Select(xx => xx.SoundRecordingId).Take(20).ToList();