Entity Framework 动态报表





5.00/5 (9投票s)
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...
}
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)
例如,关于学生平均分数的报表如下所示:
结果 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