平时做报表大都使用ADO.NET填充数据集来处理,今天尝试了下用Linq来做,也很方便,不过稍微费了一番周折。
一、准备工作
1、Northwind数据库
2、开发环境:VS2008 + SQL Server 2008
3、本测试采用网页形式,WinForm大同小异,感兴趣的朋友可以自己测试下
二、制作报表
这次先用rdlc测试,下次改用水晶报表试试。报表的布局还是很简单的,由于是测试,只放了很少的控件:
核心控件是一个Table,添加了三列,页眉放置了一个Label,为了便于查询,报表添加了一个参数:p_Country,当用户选择后可以即时查询信息。
三、准备数据源
这一步是关键,经典的DataSet拖拽方式早已经深入人心,通过Server Explorer拖拽几个表过来,再从Website Data Source中拖拽相应的字段,就好了。但是Linq呢?你会发现Website Data Source中除了三个节点外空空如也:
根本就没有我们所需要的字段,又怎么拖拽呢?我查找了一些资料,发现用存储过程是可以的,首先定义好存储过程,在数据库中执行,然后更新Northwind.dbml文件,将新创建的存储过程拖拽到方法栏中:
然后 Ctrl + Shift + S 全部保存,再打开报表时就能发现需要的字段了:
下面就是熟悉的步骤:拖拽、居中对齐、加粗...
四、后台代码
前台准备工作完成后,剩下的工作就轻松多了。在WebForm上放置了一个ReportViewer控件,用来呈现报表,同时有一个DropDownList供用户选择:
初始化DropDownList的数据源,查询出Customers表中的所有Country(去除重复值):
{
NorthwindDataContext ctx = new NorthwindDataContext();
var result = from c in ctx.Customers
select c.Country;
foreach ( string list in result.Distinct < string > ().ToList < string > ())
{
this .ddlCountry.Items.Add(list);
}
}
最后一步:构造数据源,传递参数,刷新报表
{
NorthwindDataContext ctx = new NorthwindDataContext();
var datasource = from c in ctx.sp_LinqTest(v_strCountry)
orderby c.CustomerID
select c;
ReportParameter rpCountry = new ReportParameter( " p_Country " , v_strCountry);
this .rvNorthwind.LocalReport.SetParameters( new ReportParameter[] { rpCountry });
this .rvNorthwind.LocalReport.DataSources.Add( new ReportDataSource( " sp_LinqTestResult " , datasource.ToList()));
this .rvNorthwind.LocalReport.Refresh();
}
最终效果图如下:
小结:
用Linq做数据源虽然可以实现,但是相对于传统的DataSet,其效率值得考虑,尤其当数据量很大时,报表的反应速度尤其重要,现在微软对Linq做数据源的支持还不够“官方”,期待VS2010中有何新特性吧!
本次我也留下了一些疑问:
1、不用存储过程(或视图)是否可行呢?
2、能否从后台编程获取RDLC的控件实例?
3、能否操作RDL语言来嵌入Linq呢?
4、如果Linq返回了匿名类型该如何拖拽呢?