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

Silverlight 4, Ria Services, 和 Entity Framework Complex Types

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.22/5 (8投票s)

2011 年 3 月 8 日

CPOL

3分钟阅读

viewsIcon

53920

downloadIcon

2212

如何在客户端使用复杂类型。

引言

本文将演示如何构建一个使用(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。

SL4RiaComplexTypes/1_Create_Data_Access_Layer.jpg

将实体框架模型添加到 DAL

SL4RiaComplexTypes/2_Create_Entity_Framework.jpg

选择存储过程“Employee Sales by Country”到实体模型。将使用此存储过程,因为它将返回一个复杂类型(来自多个表的字段)。

SL4RiaComplexTypes/3_EFChooseDataObjects.jpg

调出“模型视图”浏览器,以便我们轻松导航到实体模型。

创建/导入 C# 函数,该函数将表示在 DAL 中调用实体方法的方法。

SL4RiaComplexTypes/5_CreateFunctionToCallSproc.jpg

为存储过程创建复杂类型(类)。

SL4RiaComplexTypes/4_Create_Complex_Type.jpg

您的 DAL 项目结构应如下所示

SL4RiaComplexTypes/6_EntityFrameworkProjectStructure.jpg

创建 WCF 服务项目

将新的 WCF 服务添加到项目中的 WCF 解决方案文件夹。

SL4RiaComplexTypes/9_Create_Wcf_Service.jpg

在您的引用中添加对数据访问层项目的引用

SL4RiaComplexTypes/10_Add_DAL_dll_To_WCF.jpg

这就是您新添加的 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 项目

SL4RiaComplexTypes/12_CreateSilverlightApplication.jpg

为 RIA 服务启用 Silverlight 项目,并为其分配 OrdersService 服务。

SL4RiaComplexTypes/13_Enable_Ria_Services.jpg

添加对 WCF 服务的引用

SL4RiaComplexTypes/14_Add_WCF_Ref_To_SL.jpg

添加服务引用后的 Silverlight 项目

SL4RiaComplexTypes/15_SL_Structure_After_Adding_WCF_Service.jpg

将以下代码添加到 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>

这是整体项目结构

SL4RiaComplexTypes/16_SolutionStructure.jpg

屏幕输出

SL4RiaComplexTypes/Grid.jpg

关注点

顺便提一下,我发现通过设计数据访问层、WCF 服务,然后创建 Silverlight 应用程序,可以更容易地将 Silverlight 应用程序绑定到 WCF 服务(启用 RIA 服务)——我发现首先创建 Silverlight 应用程序,没有要绑定的 RIA 服务(但仍然启用 RIA 服务),这意味着当我稍后启用它们时,它没有选择服务。

© . All rights reserved.