I have the following query:
var content = (from ca in db.ContentAccesses
where !candidateList.Contains(ca.Content) &&
ca.DateAccessed >= DateTime.Now.AddDays(-90)
group ca by ca.ContentId)
.OrderByDescending(c => c.Count()).Take(5);
Which is resolving to the following T-SQL
SELECT TOP (5) [t1].[ContentId] AS [Key]
FROM (
SELECT COUNT(*) AS [value], [t0].[ContentId]
FROM [dbo].[ContentAccesses] AS [t0]
WHERE (NOT ([t0].[ContentId] = @p0)) AND ([t0].[DateAccessed] >= @p1)
GROUP BY [t0].[ContentId]
) AS [t1]
ORDER BY [t1].[value] DESC
But I need the actual "Content" objects, not just the ContentId's... so I've tried adding select ca.Content
after the group by
but compiler开发者_开发技巧 will complain.
ContentAcceses has a FK (ContentId) to Content table.
I don't understand LINQ quite well yet.
You need to flatten the groupings down to get the individual objects from the group. However since you wanted to group each ContentAccess
's Content
, you should group by that as well.
var content = (from ca in db.ContentAccesses
where !candidateList.Contains(ca.Content)
&& ca.DateAccessed >= DateTime.Now.AddDays(-90)
group ca by ca.ContentId into g
orderby g.Count() descending
from ca in g // flatten the group
select ca)
.Take(5);
For the sake of having a simpler equivalent TSQL query, you might want to use LINQ to Objects to do the flattening and get the first 5.
var content = (from ca in db.ContentAccesses
where !candidateList.Contains(ca.Content)
&& ca.DateAccessed >= DateTime.Now.AddDays(-90)
group ca by ca.ContentId into g
orderby g.Count() descending
select g)
.AsEnumerable() // use LINQ to Objects
.SelectMany(g => g) // flatten the group
.Take(5);
var content = (from ca in db.ContentAccesses
where !candidateList.Contains(ca.Content) &&
ca.DateAccessed >= DateTime.Now.AddDays(-90)
group ca by ca.ContentId into cag
select new
{
ContentId = cag.Key,
Contents = cag
}).OrderByDescending(c => c.Contents.Count()).Take(5);
精彩评论