Reputation: 781
Working with Entity Framework in ASP.Net MVC 4, and need to use linq to output a line of information.
I have an ArticleView table and an Article table. I need to output an article with the most activity within a 24 hour period.
Here's my ArticleView table:
int ArticleID
DateTime ViewCreated
Article table:
int ID
string title
Sample Data:
ArticleView:
ArticleID ViewCreated
2 4/8/2014 1:48:40 PM
2 4/8/2014 1:50:40 PM
2 4/8/2014 1:55:20 PM
3 4/8/2014 12:07:30 PM
Note: ViewCreated is automatically generated once someone views an article.
Article:
ID Title
2 Article2
3 Article3
Expected Output:
Article with the most activity within 24 hours is:
Article2(3)
What I have to work with:
var articles = db.Articles;
var articleviews = db.ArticleViews;
Just not sure how to approach this.
Upvotes: 3
Views: 111
Reputation: 13399
To get the article you can simply do this:
var article = db.Articles.OrderByDescending(a=>a.ArticleViews.Count())
.Take(1).FirstOrDefault();
Or
var article = db.Articles.OrderByDescending(a=>a.ArticleViews.Count())
.FirstOrDefault()//this should work too
One shorter way of a suggested solution here is:
var mostViewedArticle = db.ArticleViews
.Where(av => av.ViewCreated >= startDateTime && av.ViewCreated < endDateTime)
.GroupBy(av => av.ArticleId)
.OrderByDescending(g=> g.Count())
.Select(g => g.First().Article)
.Take(1)
Article
through navigation propertyFirst
one. Upvotes: 0
Reputation: 6026
You can do this is one statement by using a join:
var mostViewedArticleTitleAndCount = db.Articles
.Join(ArticleViews.Where (av => av.ViewCreated > sinceDate),
a => a.ID,
v => v.ArticleID,
(a,v) => new { a,v })
.GroupBy (g => g.a.ID)
.Select (g => new { g.Key, Title = g.First ().a.Title, Count = g.Count ()})
.OrderByDescending (g => g.Count)
.Select (g => g.Title + "(" + g.Count + ")")
.First ();
For your test data this will output:
Article2(3)
Upvotes: 0
Reputation: 1610
Something like this:
var viewsById = db.ArticleViews
.Where(av => av.ViewCreated >= startDateTime && av.ViewCreated < endDateTime)
.GroupBy(av => av.ArticleId)
.Select(g => new { ArticleId = g.Key, Count = g.Count() })
var highestCount = viewsById.Max(v => v.Count);
var topArticles = viewsById.Where(a => a.Count == highestCount);
var topArticle = topArticles.First();
var message = String.Format("Article id: {0}, views: {1}",
topArticle.ArticleId, topArticle.Count);
Upvotes: 2