2014-04-08 87 views
3

在ASP.Net MVC 4中使用实体框架,并需要使用linq输出一行信息。Linq with multiple tables

我有一个ArticleView表和一个Article表。我需要在24小时内输出活动最多的文章。

这里是我的ArticleView表:

int ArticleID 
DateTime ViewCreated 

文章表:

int ID 
string title 

样本数据:

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 

注意:一旦有人查看文章,ViewCreated会自动生成。

Article: 
    ID  Title 
    2  Article2 
    3  Article3 

预期输出:

文章最活动的24小时内是:

第二条(3)

我有什么一起工作:

var articles = db.Articles; 
var articleviews = db.ArticleViews; 

只是不知道如何解决这个问题。

回答

2

像这样:

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); 
  1. 过滤器的观点是在指定的日期范围内。
  2. 按文章ID对它们进行分组。
  3. 制作每个对象的匿名对象,存储文章ID和该文章的视图数量。
  4. 取最高计数的那个。
0

你可以做到这一点是通过使用连接一个声明:

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(); 

为您的测试数据,该输出:

第二条(3)

0

要拿到文章你可以简单地做到这一点:

var article = db.Articles.OrderByDescending(a=>a.ArticleViews.Count()) 
       .Take(1).FirstOrDefault(); 

或者

var article = db.Articles.OrderByDescending(a=>a.ArticleViews.Count()) 
       .FirstOrDefault()//this should work too 

建议的解决方案的一个简短的形式在这里:

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) 
  1. 过滤一些日期范围
  2. 分组的条款ArticleID
  3. 排序方式最依次排列
  4. 选择th e Article通过导航属性
  5. 只取First一个。