c# - 使用外键对多个表进行分组

标签 c# linq entity-framework group-by

我有两个表,我从 Views 计算帖子浏览量表使用ViewDate列,然后我想得到 PostTItle使用.GroupBy对于使用外键的 Entity Framework PostID .

Posts表:

PostID   PostTitle
--------------------
1         post one
2         post two 
3         post three
4         post four
5         post five
6         post six

Views表:

ViewID     ViewDate             PostID   
---------------------------------------
  1        2015 07 17 19:00:00        1
  2        2015 07 17 20:00:00        1
  3        2015 07 17 21:00:00        2
  4        2015 07 18 19:00:00        2
  5        2015 07 19 19:00:00        2
  6        2015 07 21 19:00:00        1
  7        2015 07 23 19:00:00        2

到目前为止,这就是我所做的

    return _db.ObjectSet.Where(p => DateTime.Now >= EntityFunctions.AddDays(p.ViewDate, -14))
        .GroupBy(y => y.PostID, y => y.ViewDate, (ID, Date) => new ExampleViewModel
        {
            Post_ID = ID,
            View_Date = Date.Count()
        }).OrderByDescending(z => z.View_Date).Take(5);

但是使用这个解决方案我只能分配 Post_IDView_DateExampleViewModel ,我怎样才能得到PostTitle使用外键?

注意:我正在尝试获取过去 14 天内浏览次数最多的(热门)帖子

请帮忙

预期输出:

Title:post one, Id:1, Views:3
Title:post two, Id:2, Views:4

最佳答案

一种解决方案可能是在这些实体之间应用 join 并将 PostTitle 包含在您想要分组的字段中:

var query= (from v in db.Views
            join p in db.Posts on v.PostID equals p.Id
            where  DbFunctions.DiffDays(v.ViewDate,DateTime.Now)<=14
            group new{v,p} by new {v.PostID, p.PostTitle, v.ViewDate} into g
            let count=g.Count()
            orderby count descending
            select new{ Post_ID=g.Key.PostID, View_Date=count, Title= g.Key.PostTitle}
           ).Take(5);

如您所见,我使用的是 DbFunction 类,而不是 EntityFunctionDbFunctions 类是在 Entity Framework 6 中引入的,它与 .NET Framework 分开提供。对于使用从 6.0 开始的 EF 版本的任何新应用程序,您应该使用 DbFunctions 类。无论如何,如果您现在不想使用该类,您也可以使用 EntityFunctions.DiffDays 方法。

现在,如果两个实体相关:

public class Post
{
  public int ID{get;set;}
  // ...
  public virtual ICollection<View> Views{get;set;}
}
public class View
{
  public int ID{get;set;}

  public int PostID{get;set;}
  // ...
  public virtual Post Post{get;set;}
}

您也可以这样做:

var query= (from v in db.Views
            where  DbFunctions.DiffDays(v.ViewDate,DateTime.Now)<=14
            group v by new {v.PostID, v.ViewDate} into g
            let count=g.Count()
            orderby count descending
            select new{ Post_ID=g.Key.PostID, View_Date=count, Title= g.First().Post.PostTitle}
           ).Take(5);

更新 1

要避免使用 EntityFunctions 类,您可以将当前日期减去 14 天,然后直接比较查询中的两个日期:

 var date = DateTime.Now.AddDays(-14);
 var query= (from v in db.Views
             join p in db.Posts on v.PostID equals p.Id
             where  v.ViewDate>=date
             group new{v,p} by new {v.PostID, p.PostTitle, v.ViewDate} into g
             let count=g.Count()
             orderby count descending
             select new{ Post_ID=g.Key.PostID, View_Date=count, Title= g.Key.PostTitle}
         ).Take(5);

更新2

那是因为您是按日期分组的。要获得您期望的结果,您需要从正在分组的元素中删除该字段:

  var query= (from v in db.Views
              join p in db.Posts on v.PostID equals p.Id
              where  v.ViewDate>=date
              group new{v,p} by new {v.PostID, p.PostTitle} into g
              let count=g.Count()
              orderby count descending
              select new{ Post_ID=g.Key.PostID, View_Date=count, Title= g.Key.PostTitle}
             ).Take(5);

关于c# - 使用外键对多个表进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31756333/

相关文章:

c# - 如何从 Web.config 获取常量字符串?

c# - 实现一个 Dictionary<int, Dictionary<int, int>>,键的顺序?

c# - 如何将 Javascript 注册到 CS 文件?

c# 替换字符串中字符选择的每个实例

c# - 当类型相同时,连接子句中的一个表达式的类型不正确

c# - 如何在 Entity Framework 5 中表达 "has many through"关系?

c# - 在 C# 中验证模块化和校验和

c# - Lambda 表达式为列表中的每个不同值返回一个结果

c# - 使用两列的 Linq 查询分组数据表

c# - Entity Framework 6 + MySQL : Model tables are not created automatically