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

介绍 Composite Data Service Framework

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2011年11月27日

CPOL

5分钟阅读

viewsIcon

31938

downloadIcon

524

使用 Composite Data Service Framework, 使用单个 Data Service 公开来自多个来源的数据!

CDSF-Logo.png

引言

欢迎!在本系列文章中,我将向您展示如何执行一些高级 OData/WCF 数据服务任务,例如创建自定义数据服务提供程序、自定义服务引用的生成等等。首先,我将描述 WCF 数据服务的一些局限性,然后说明我们将如何解决这些问题。

WCF 数据服务的局限性

WCF 数据服务非常出色,但目前存在一些关键的局限性。

  • 将多个数据源聚合到一个数据服务中很困难。
  • 用标准 WCF 服务增强 WCF 数据服务非常困难。
  • 未为服务操作生成客户端代理。

存在一些更微妙的局限性,我们稍后会看到。

运行示例服务

这是开始使用示例服务的方法。

  1. 打开 CompositeDataServiceFramework 解决方案。
  2. 双击文件 Samples > Composite Data Service Sample > CreateDatabases.sql。
  3. 运行此脚本(如果您没有安装完整的 MS SQL Server,SQL Server Express Edition 也可以作为数据库平台)。
  4. 运行 CompositeDataServiceSample 项目。
  5. 浏览到 https://:65110/CompositeDataServiceSample.svc/$metadata,我们可以看到 CompositeDataService 已将我们的 Orders 和 Users 数据服务组合成一个单一的数据服务 - 并且该服务功能齐全。

复合数据服务框架

考虑到这些局限性,我创建了一个名为 Composite Data Service Framework 的项目。该项目的主要目标是允许将多个数据源聚合在一起,创建一个单一的复合 WCF 数据服务,如下图所示。

CSDF_Diagram.png

创建复合数据服务

创建复合数据服务非常简单。首先,为要公开的每个模型添加一个 WCF 数据服务类 - 在提供的示例解决方案中,我有两个模型 - 一个 OrdersDataModel 和一个 UsersDataModel。这些模型是 Entity Framework 数据模型。现在创建另一个 WCF 数据服务,命名为“CompositeDataService”之类的名称。您现在需要做的就是派生自 CompositeDataService 并将每个不同的 WCF 数据服务添加为 CompositeDataSource

以下是分步操作方法。

首先,通过向应用程序添加 WCF 数据服务来创建复合数据服务。

/// <summary>
/// This is an example of a composite data service.
/// </summary>
public class CompositeDataServiceSample : 
       CompositeDataServiceFramework.Server.CompositeDataService
{
    /// <summary>
    /// A WcfDataServiceDataSource for the Orders Data Service.
    /// </summary>
    private WcfDataServiceDataSource<OrdersModelContainer> ordersDataService;

    /// <summary>
    /// A WcfDataServiceDataSource for the Users Data Service.
    /// </summary>
    private WcfDataServiceDataSource<UsersDataModelContainer> usersDataService;

我们在这里所做的是创建了一个复合数据服务,它有两个数据源成员 - 一个用于我们的用户模型,一个用于我们的订单模型。接下来,我们像初始化任何普通 WCF 数据服务一样初始化我们的服务 - 为每个对象和操作指定访问权限。

/// <summary>
/// Initializes the service.
/// </summary>
/// <param name="config">The config.</param>
public static void InitializeService(DataServiceConfiguration config)
{
    //  Allow full access to all entity sets and all service operations.
    config.SetEntitySetAccessRule("*", EntitySetRights.All);
    config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}

最后,在构造函数中,我们构建两个数据源并将它们添加到复合数据服务中,然后对其进行初始化。

/// <summary>
/// Initializes a new instance of the <see cref="CompositeDataServiceSample"/> class.
/// </summary>
public CompositeDataServiceSample()
{
    //  Create the orders data source, by providing
    //  an Orders Data Service, Orders Model Container
    //  and the Url to the data service.
    ordersDataSource = new WcfDataServiceDataSource<OrdersModelContainer>(
        new OrdersDataService(),
        new OrdersModelContainer(),
        new Uri("https://:65110/OrdersDataService.svc"));

    //  Create the users data source, by providing
    //  a Users Data Service, Users Model Container
    //  and the Url to the data service.
    usersDataSource = new WcfDataServiceDataSource<UsersDataModelContainer>(
        new UsersDataService(),
        new UsersDataModelContainer(),
        new Uri("https://:65110/UsersDataService.svc"));
    
    //  Add each data source.
    AddDataSource(ordersDataSource);
    AddDataSource(usersDataSource);

    //  Initialise the data service.
    Initialise();
}

现在您可以运行数据服务并在 URL 末尾添加 /$metadata - 这个单一的数据服务将其他两个数据服务聚合到一个中!

现在,当您在客户端项目中为复合数据服务添加引用时,您可以访问两个服务中的实体;从客户端的角度来看,无论它们来自哪里,它们都作为同一服务的一部分呈现。

它是如何工作的?

此项目中已有大量代码,而且随着我构建完整的功能集,代码还会更多。因此,我不会像在大多数文章中那样逐行查看代码,而是将以更高层次的方式描述代码。

创建自定义数据服务

首先要做的就是派生一个类自 Data Service。这将是代表复合数据服务的主要对象。此对象还必须实现 IServiceProvider 接口,以允许实例化支持接口的实例。

现在必须支持以下接口(在此框架中,每个接口都在其自己的类中)。

IDataServiceMetadataProvider

IDataServiceMetadataProvider 接口公开有关服务本身的信息 - 它公开了哪些集合、它公开的对象类型、其服务操作以及对象之间的关系。

IDataServiceQueryProvider

IDataServiceQueryProvider 接口允许实际查询数据服务中的数据。其中最重要的函数是 GetQueryRootForResourceSet,它必须返回一个特定资源集的 IQueryable

IDataServiceUpdateProvider

IDataServiceUpdateProvider 接口公开了启用对元数据提供程序中定义并在查询提供程序中公开的数据的操作的功能。它允许更新、删除数据等。

保持更新

复合数据服务框架托管在 CodePlex 上:http://cdsf.codeplex.com/。项目路线图在主页上。我欢迎任何建议或想法!随着项目的开发,我们将完成以下任务:

  • 允许将 Entity Framework 模型用作复合数据源 - 无需先由 WCF 数据服务公开。
  • 允许使用标准 CLR 对象集合作为复合数据源。
  • 通过展示如何创建用于将属性标记为仅客户端使用的特殊属性,来演示客户端服务引用创建的自定义。
  • 演示添加服务引用时如何自动生成服务操作代理。
  • 展示如何使用自定义模板来扩展 Visual Studio 的项目和项,并展示如何使用向导来自定义这些项的生成。

延伸阅读

Alex D James 的博客“Meta-Me”上有一系列关于如何创建自定义数据服务的精彩帖子 - 第一篇帖子在此:http://blogs.msdn.com/b/alexj/archive/2010/01/07/data-service-providers-getting-started.aspx

复合数据服务框架托管在 CodePlex 上:http://cdsf.codeplex.com/

我在我的博客 http://www.dwmkerr.com 上发布了各种关于我的项目持续开发的文章。

© . All rights reserved.