在ADO.net实体数据模型上执行聚合计数()

时间:2018-02-20 13:43:52

标签: sql entity-framework linq listview aggregate-functions

我正在尝试执行聚合count(),就像SQL查询对我的数据库一样,但是我想使用LINQ而不是SQL。

我正在尝试使用 LINQ 查询实体框架数据模型并执行汇总和()。具体来说,我想计算TimeEntry表中的列(TimeWorked),按项目名称和2个特定日期之间的阶段进行分组,然后在Project表上进行自然连接。然后我将获取该查询结果并将其加载到一个可观察的集合中并将其显示在ListView中。

我想要的结果是[ProjectName],[Phase],[Count(TimeWorked)],[Date] 我想将计数过滤到只有两个日期之间的TimeEntry的项目,为了这个例子,它只被称为Date1和Date2。

我还不熟悉LINQ 100%,我还在学习,请原谅我缺乏LINQ术语。

这是我的关系和表格的图片。 DB Schema

以下是数据类型 Project Table data typesTimeEntry table

我一直在寻找各处,似乎找不到任何好的资源或例子。有人可以指出我正确的方向。

1 个答案:

答案 0 :(得分:1)

所以你有项目和时间。 Project和TimeEntry之间存在一对多的关系:每个Project都有零个或多个TimeEntries,每个TimeEntry只属于一个Project。

如果你跟着the entity framework code first conventions,,你就会创建这样的类:

class Project
{
    public int Id {get; set;}

    // every Project has zero or more TimeEntries:
    public virtual ICollection<TimeEntry> TimeEntries {get; set;}

    ... // other properties
}
class TimeEntry
{
    public int Id {get; set;}

    // every TimeEntry belongs to exactly one Project using foreign key:
    public int ProjectId {get; set;}
    public virtual Project Project {get; set;}

    ... // other properties
}
class MyDbContext : DbContext
{
    public DbSet<Project> Projects {get; set;}
    public DbSet<TimeEntry> TimeEntries {get; set;}
}

因为您遵循了约定,所以这足以告知实体框架您计划的一对多。实体框架将能够检测主键和外键以及Projects和TimeEntries之间的关系(可能的问题:时间条目的多元化)。

如果您需要不同的表名或列名,则需要属性或流畅的API。但结构仍然相似。

现在你有了Project和TimeEntries。你想为每个项目提供TimeWorked在给定时间间隔内的TimeEntries数量(你确定吗?你想要Count,而不是工作时间的总和?)

我会这样做:

var projectWithCountTimeWorked = dbContext.Projects
    .Select(project => new
    {
        ProjectName = project.ProjectName,
        ...

        // the Count of TimeEntries of this project in this period:
        CountTimeWorked = project.TimeEntries
            .Where(timeEntry => minDate <= timeEntry.TimeWorked
                 && timeEntry.TimeWorked <= maxDate)
            .Count(),
    });

因为我使用了ICollections,实体框架将在内部进行正确的连接以计算结果。

如果你想自己指定连接,我会选择:

var result = dbContext.Project           // GroupJoin Projects
    .GroupJoin(dbContext.TimeEntries     // and TimeEntries
    project => project.Id,               // from every Project take the Id
    timeEntry => timeEntry.ProjectId,    // from every timeEntry take the ProjectId
    (project, timeEntries) => new        // for every Project and his matching
    {                                    // timeEntries make a new object
        Name = project.Name,
        ...
        CountTimeWorked = timeEntries    // count all timeEntries during the period
            .Where(timeEntry => minDate <= timeEntry.TimeWorked
                 && timeEntry.TimeWorked <= maxDate)
            .Count(),

如果您不熟悉实体框架代码的第一个基础知识。 This web site helped me a lot to get me on track

Ťhis article was a good summary for me to have a look at most used linq methods