Silverlight 4, Ria Services, 和 Entity Framework Complex Types






4.22/5 (8投票s)
如何在客户端使用复杂类型。
- 下载源代码 - 2.63 MB
请记住更改服务和数据访问层中的连接字符串。
引言
本文将演示如何构建一个使用(Entity Framework)复杂类型的 Silverlight 4 应用程序,在客户端级别(通过 WCF 服务)。
背景
在 Silverlight 4 之前,无法在客户端使用复杂类型,但现在,Silverlight 4 可以使用 RIA 服务来访问 Entity Framework 创建的(Complex)类型。在以前的 Silverlight 版本中,可以访问简单的实体类型,但不能访问复杂类型。
使用代码
设置示例数据库
如果您没有在数据库服务器上安装 Microsoft 的 Northwind 数据库,您可以在这里下载脚本 (下载脚本 - 238 KB)。登录到您的 SQL Server Management Studio 并打开一个新的查询分析器窗口,运行解压缩的脚本以创建数据库(包括数据),该数据库用于项目中的数据访问层 (DAL)。
创建一个新的(空的)项目,并为数据访问层、WCF 服务和 Silverlight 客户端添加三个解决方案文件夹。
创建数据访问层 (Entity Model) 项目
通过向项目中的“数据访问层”解决方案添加一个新的类库来创建数据访问层 DLL。
将实体框架模型添加到 DAL
选择存储过程“Employee Sales by Country”到实体模型。将使用此存储过程,因为它将返回一个复杂类型(来自多个表的字段)。
调出“模型视图”浏览器,以便我们轻松导航到实体模型。
创建/导入 C# 函数,该函数将表示在 DAL 中调用实体方法的方法。
为存储过程创建复杂类型(类)。
您的 DAL 项目结构应如下所示
创建 WCF 服务项目
将新的 WCF 服务添加到项目中的 WCF 解决方案文件夹。
在您的引用中添加对数据访问层项目的引用
这就是您新添加的 WCF 项目中的 DAL 项目。
将以下代码添加到 IOrdersService
类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using OrdersAccessLayer;
namespace WcfOrdersService
{
[ServiceContract]
public interface IOrdersService
{
/// <summary>
/// Gets the order details data.
/// </summary>
/// <param name="start">The start.</param>
/// <param name="end">The end.</param>
/// <returns>A collection of complex type classes
/// 'Employee_Sales_by_Country_Result'</returns>
[OperationContract]
List<Employee_Sales_by_Country_Result>
GetOrderDetailsData(DateTime start, DateTime end);
}
}
将以下代码添加到 OrdersService
类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using OrdersAccessLayer;
namespace WcfOrdersService
{
public class OrdersService : IOrdersService
{
/// <summary>
/// A reference to the controller class in the DAL project
/// </summary>
private OrdersController orderCtrl;
/// <summary>
/// Initializes a new instance of the <see cref="OrdersService"/> class.
/// </summary>
public OrdersService()
{
orderCtrl = new OrdersController();
}
/// <summary>
/// Gets the order details data.
/// </summary>
/// <param name="start">The start.</param>
/// <param name="end">The end.</param>
/// <returns></returns>
public List<Employee_Sales_by_Country_Result>
GetOrderDetailsData(DateTime start, DateTime end)
{
return this.orderCtrl.GetOrderDetails(start, end);
}
}
}
在将其添加到下面的 Silverlight 项目之前编译服务。
创建 Silverlight 4 客户端项目
创建一个新的 Silverlight 项目
为 RIA 服务启用 Silverlight 项目,并为其分配 OrdersService 服务。
添加对 WCF 服务的引用
添加服务引用后的 Silverlight 项目
将以下代码添加到 MainPage.cs 的代码隐藏中。请注意,在 SaveScheduleCompleted
方法中,对 (实体类) 'Employee_Sales_By_Country_Result
' 的集合执行了一些 LINQ。因此,我们可以在 Entity Framework 中创建一个类,并且还可以在客户端中使用它。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Silverlight4Console.OrdersServiceReference;
using System.ServiceModel;
namespace Silverlight4Console
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.LoadOrderDetails();
}
private void LoadOrderDetails()
{
try
{
DateTime start = DateTime.Parse("1997-01-01");
DateTime end = DateTime.Parse("1997-01-31");
OrdersServiceReference.OrdersServiceClient ordersService =
new OrdersServiceReference.OrdersServiceClient();
ordersService.GetOrderDetailsDataAsync(start, end);
ordersService.GetOrderDetailsDataCompleted +=
new EventHandler<GetOrderDetailsDataCompletedEventArgs>(
SaveScheduleCompleted);
}
catch (FaultException fe)
{
Console.WriteLine(fe.Message);
Console.WriteLine("stack trace");
Console.WriteLine(fe.StackTrace);
Console.ReadLine();
}
catch (CommunicationException commProblem)
{
if (commProblem.InnerException is FaultException)
{
Console.WriteLine("An unknown exception was received. " +
commProblem.InnerException.Message);
Console.ReadLine();
return;
}
else
{
Console.WriteLine("There was a communication problem. " +
commProblem.Message);
Console.WriteLine(commProblem.StackTrace);
}
}
}
/// <summary>
/// Saves the schedule completed.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see
/// cref="RiaConsole.TemplateService.SaveScheduleCompletedEventArgs"/>
/// instance containing the event data.</param>
private void SaveScheduleCompleted(object sender,
GetOrderDetailsDataCompletedEventArgs e)
{
this.personDataGrid.ItemsSource = e.Result.Where(ord=>ord.SaleAmount>2000);
}
}
}
将以下 XAML 代码添加到 MainPage
(一个用于绑定/显示订单结果的简单网格)
<UserControl x:Class="Silverlight4Console.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
<Grid x:Name="LayoutRoot" Background="White">
<sdk:DataGrid AutoGenerateColumns="true" VerticalAlignment="Center"
HorizontalAlignment="Center" Height="100"
Margin="57,66,0,0" Name="personDataGrid" Width="auto" />
</Grid>
</UserControl>
这是整体项目结构
屏幕输出
关注点
顺便提一下,我发现通过设计数据访问层、WCF 服务,然后创建 Silverlight 应用程序,可以更容易地将 Silverlight 应用程序绑定到 WCF 服务(启用 RIA 服务)——我发现首先创建 Silverlight 应用程序,没有要绑定的 RIA 服务(但仍然启用 RIA 服务),这意味着当我稍后启用它们时,它没有选择服务。