65.9K
CodeProject 正在变化。 阅读更多。
Home

Entity Framework 动态报表

starIconstarIconstarIconstarIconstarIcon

5.00/5 (9投票s)

2015年9月5日

CPOL

2分钟阅读

viewsIcon

30612

downloadIcon

1052

EF Dynamic Report 是一个小型开源项目,允许您使用 Entity Framework 在类型和表之间进行映射,作为动态报表数据源。

引言

自从 Entity Framework 6.1 以来,你可以使用 EF 元数据来揭示关于数据库结构的信息。你可以在这里找到关于这种方法的良好解释:类型与表之间的映射

在本文中,我想展示如何基于 EF 元数据轻松创建动态报表。
主要思想是从 EF 映射中收集所需表和列的信息,然后构建一个 SQL 查询,该查询将返回客户所需的所有信息。

这种方法的主要优点是

  • 报表与数据库结构分离。

  • 代码重用,数据库信息将从实体框架映射中获取。

  • 轻松扩展报表。

我创建了一个小型库,它使用了描述的方法,可以简化与动态报表的工作。所有源代码都可以在 GitHub 上找到:EFDynamiReport

下面我将描述如何使用这个小型库快速设置你的动态报表,该库可以轻松添加到你的项目中

使用代码

1. 设置你的实体框架映射。

本文不涵盖有关使用实体框架的所有细节,但你可以在这里找到许多有用的文章。
对于我们的演示项目,我们将使用一个简单的数据库模式,其中包含有关学校学生的信息。

public class Student
{
    [Key]
    public int StudentId { get; set; }

    public string FirstName { get; set; }

    //some code removed for brevity...
}

public class SchoolDbContext : DbContext
{
     public DbSet<Student> Students { get; set; }

    //some code removed for brevity...
}

Data Base structure.

2. 配置报表模板

对于每个报表,我们应该声明哪些列将在其中可用。
在我们的例子中,为此目的我们使用报表模板类 StudentsReport,其中包含有关所有将在报表中可用的列的信息。

public class StudentsReportTemplate : ReportTemplate
{
    ///some code removed for brevity...

    public override IEnumerable<IReportColumn> ReportColumns
    {
        get
        {
           return new List<IReportColumn>
                {
                    StudentTable.Column("First Name", x => x.FirstName),
                    StudentTable.Column("Last Name", x => x.LastName),
                    StudentTable.Column("Phone", x => x.Phone),
                    StudentTable.Column("Home Adress", x => x.HomeAdress),
                    new AverageScore(queryExtractor, StudentTable).Column("Average Score"),
                    new MinimumScore(queryExtractor, StudentTable).Column("Minimum Score"),
                    new MaximumScore(queryExtractor, StudentTable).Column("Maximum Score"),
                    new Age(StudentTable).Column("Age"),
                    new Subjects(queryExtractor, StudentTable).Column("Subjects")
                };
        }
    }

    public override IReportDataSource ReportDataSource
    {
        get { return StudentTable.GetReportDataSource(); }
    }
}

每个语句声明报表中的一个可能的列。
例如:StudentTable.Column("First Name", x => x.FirstName) 声明报表可以包含学生的名字。

如果你将只包含一个“First Name”列的报表,结果 SQL 查询将如下所示

SELECT 
    s.FirstName 
FROM 
    [dbo].[Students] AS s

3. 创建报表并从中获取报表数据

在配置报表模板后,我们可以从中创建报表模型。

StudentsReportTemplate template = new StudentsReportTemplate(...);

//Report Template create IReportModel object which do not depend from concrete report template.
IReportModel reportModel = template.CreateReport();

为了获取报表数据,我们指定要在报表中查看哪些列和筛选器(所有列都应存在于报表中,有关更多详细信息,请参阅步骤 #2)

var filters = new IReportFilter[0];    
var columns = new IReportColumn[]
{
    new ReportColumn { Title = "First Name"}
}   

var data =  reportModel.Get(columns, filters)

例如,关于学生平均分数的报表如下所示:

Report Example.

结果 SQL 查询将如下所示

SELECT 
    ( SELECT AVG(e.Score)  FROM ExamenResults as e WHERE e.StudentId = s.StudentId) AS AverageScore,
    s.FirstName AS FirstName 
    s.LastName AS LastName
FROM 
    FROM [dbo].[Students] AS s

历史

你可以在 GitHub 上找到所有源代码: EF Dynamic Report

© . All rights reserved.