在本文中,将探讨如何利用Reporting Services和Silverlight技术结合RIA Services来创建商业报告。假设读者已经具备Silverlight、RIA Services、C#以及WCF和Entity Framework的基础知识。
首先,在Visual Studio 2010中创建一个Silverlight应用程序。这里使用Silverlight商业应用程序模板。
在ASP.NET项目中,添加一个Entity Framework模型。在这个示例中,将使用AdventureWorksLT数据库。以下是将在示例中使用的实体:
构建项目后,将添加一个域服务类。以下是所有被选为添加到域服务的实体:
在这种情况下,使用本地模式的Reporting Services。在报告中,当添加一个Tablix组件时,会请求一个数据集。在这种情况下,
选择数据集向导会看到之前添加的域上下文。对于这个演示,创建了一个新的类,将使用它来绑定到报告。在某些情况下,这样做是更可取的,因为可能需要在数据绑定到报告之前进行一些额外的处理:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace ReportingServicesDemo.Web
{
public class Orders
{
public Orders() { }
[Key]
public int OrderDetailsID { get; set; }
public int OrderID { get; set; }
public string Product { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal UnitPriceDiscount { get; set; }
public decimal LineTotal { get; set; }
}
}
在这个类中,引用了System.ComponentModel.DataAnnotations命名空间,它允许为OrderDetailsID属性添加一个Key属性 - 这是类的要求,以便域服务可以将其识别为实体。
如果深入到域服务代码,会找到以下内容:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
///
/ 实现使用AdventureWorksLT2008Entities上下文的应用逻辑。
///
/ TODO: 在这些方法中添加应用逻辑或在其他方法中添加。
///
/ TODO: 连接认证(Windows/ASP.NET Forms)
///
和取消注释以下内容以禁用匿名访问
///
/ 也考虑添加角色以适当限制访问。
//
[RequiresAuthentication]
[EnableClientAccess()]
public class ADWLTDomainService : LinqToEntitiesDomainService<AdventureWorksLT2008Entities>
{
// ...
}
现在,创建一个域操作,它暴露了刚刚在自定义类中创建的Orders实体:
public IQueryable<Orders> GetOrderDetails(int OrderID)
{
AdventureWorksLT2008Entities adw = new AdventureWorksLT2008Entities();
var query = from c in adw.SalesOrderDetail.Include("Product")
where c.SalesOrderID == OrderID
select new Orders { OrderID = OrderID,
OrderDetailsID = c.SalesOrderDetailID,
Product = c.Product.Name,
Quantity = c.OrderQty,
UnitPrice = c.UnitPrice,
UnitPriceDiscount = c.UnitPriceDiscount,
LineTotal = c.LineTotal };
return query;
}
这里有一些注意事项。在这个方法中,使用了Entity Framework上下文而不是域服务声明的对象上下文,并将其暴露为IQueryable,就像其他选择方法一样。
如果再次构建项目,"选择数据集向导"会看到自定义方法和实体暴露的所有字段,为报告做好准备。
现在在Web项目中添加一个WebForm,以便使用ReportViewer控件放置报告:
当添加ReportViewer控件时,它会创建一个ObjectDataSource控件。查看ObjectDataSource的属性,可以看到自定义方法的Select属性。查看SelectParameters集合,可以看到自定义方法参数。
现在在Silverlight项目中,添加一个绑定到Sales Orders实体的DataGrid。在这个演示中,Sales Order ID列的每个字段都表示为一个按钮,以便在点击事件上将内容值作为参数传递。想法是使用HtmlPage对象调用一个弹出窗口,使用System.Windows.Browser命名空间中的HtmlPopup选项:
HtmlPopupWindowOptions options = new HtmlPopupWindowOptions();
options.Left = 0;
options.Top = 0;
options.Width = 930;
options.Height = 800;
options.Menubar = false;
options.Toolbar = false;
options.Directories = false;
options.Status = false;
Button btn = sender as Button;
int OrderID = int.Parse(btn.Content.ToString());
string address = Application.Current.Host.Source.AbsoluteUri;
int i = address.IndexOf("/ClientBin/", 1);
string url = address.Substring(0, i);
url = url + "/RpDemoWebForm.aspx?OrderID=" + OrderID;
if (true == HtmlPage.IsPopupWindowAllowed)
HtmlPage.PopupWindow(new Uri(url), "new", options);
可以使用Application.Current.Host.Source.AbsoluteUri属性获取Silverlight XAP应用程序正在运行的当前Web地址。稍后,可以创建与ReportViewer的Web Form关联的URI。
最后,可以查看订单详情报告。