在 Office 2010 中使用 Business Connectivity Services 连接到 .NET Framework 源

Office 可视操作方法

**摘要:**了解如何基于 .NET Framework 源创建 Office 2010Business Connectivity Services 外部内容类型。(29 个打印页)

上次修改时间: 2015年3月9日

适用范围: Excel 2010 | Office 2010 | Open XML | PowerPoint 2010 | VBA | Word 2010

**发布时间:**2010 年 2 月

**供稿人:**Joel Krist,iSoftStone

概述

与 Office 2010 和 SharePoint 2010 一起提供的 Microsoft Business Connectivity Services (BCS) 基于 Microsoft Office SharePoint Server 2007 附带的业务数据目录所提供的功能构建,以引入写回支持和丰富客户端集成等一些新功能。Visual Studio 2010 提供了业务数据连接模型项目模板和几个新工具,它们可简化创建 BCS 模型以及使用外部数据和服务的 Office 解决方案的部署的过程。此直观操作方法演示如何使用 Visual Studio 2010 创建 BCS 外部内容类型。外部内容类型连接到一个 .NET Framework 程序集,该程序集使用 Linq to XML 提供对存储在简单 XML 数据文件中的数据的读/写访问。外部内容类型显示为从 SharePoint 外部列表使用。

编码

此直观操作方法演示如何创建和使用基于 .NET Framework 的 BCS 外部内容类型:

  1. 创建 XML 数据文件以模拟后端数据存储。

  2. 在 Visual Studio 2010 中创建 SharePoint 2010 业务数据连接模型项目。

  3. 从模型中删除 Visual Studio 生成的默认实体。

  4. 将 Customer 类添加到项目中。

  5. 将 Customer 实体添加到模型中。

  6. 将对 Microsoft.BusinessData 的引用添加到项目中。

  7. 向 Customer 外部内容类型中添加代码以实现 Finder、Specific Finder、Creator、Updater 和 Deleter 构造型。

  8. 将解决方案部署到 SharePoint 并通过创建 SharePoint 外部列表测试 Customer 外部内容类型。

创建模拟后端数据存储

此直观操作方法创建一个基于 Customer 实体的外部内容类型。Customer 实体非常简单,它包含两个字段:CustomerID 和 CustomerName。为降低复杂度,此直观操作方法使用简单的 XML 数据文件来模拟客户数据的后端数据存储。以下步骤介绍如何创建客户数据文件。

  1. 启动您最喜欢的 XML 编辑器来创建新文件。

  2. 复制以下 XML 并将其粘贴到新文件中。

    <?xml version="1.0" encoding="utf-8"?>
    <Customers NextCustomerId="2">
      <Customer ID="0">
        <CustomerName>Customer 0</CustomerName>
      </Customer>
      <Customer ID="1">
        <CustomerName>Customer 1</CustomerName>
      </Customer>
    </Customers>
  3. 将新文件另存为 C:\Dev\Temp\CustomerData.xml

在 Visual Studio 2010 中创建 SharePoint 2010 业务数据连接模型项目

  1. 以管理员身份启动 Microsoft Visual Studio 2010。

  2. 在 Visual Studio 的"文件"菜单上,选择"新建",然后选择"项目"。

  3. 在"新建项目"对话框中,选择"已安装的模板"窗格中的"Visual C# SharePoint 2010"模板类型。

  4. 在模板列表中,选择"业务数据连接模型"模板。

  5. 将项目和解决方案命名为 CustomerModel。

    图 1. 创建解决方案


    创建解决方案

  6. 单击"确定"。Visual Studio 将显示"SharePoint 自定义向导"。

  7. 输入要用于部署和调试的本地网站的 URL。

    图 2. SharePoint 自定义向导


    SharePoint 自定义向导

  8. 单击"完成"以完成向导并创建解决方案。Visual Studio 将创建解决方案并在外部内容类型设计器中显示模型。

    图 3. 外部内容类型设计器中的新模型


    新建模型

从模型中删除 Visual Studio 生成的默认实体

创建新的 Business Data Connectivity 共享服务模型时,Visual Studio 将创建一个默认实体。此直观操作方法采用删除默认实体的方法,以便简化新建名为 Customer 的实体所需的步骤。

  1. 右键单击显示在"外部内容类型设计器"中的"Entity1"实体,然后从上下文菜单中选择"删除"。

    图 4. 删除默认实体


    删除默认实体

  2. 在"解决方案资源管理器"中,展开"BdcModel1"节点,右键单击"Entity1.cs",然后单击"删除"。

  3. 提示您确认删除时,请单击"确定"。对"Entity1Service.cs"文件执行相同的操作。结果为一个空的 BDC 模型。

    图 5. 空 BDC 模型


    空 BDC 模型

将 Customer 类添加到项目中

Customer 类封装了客户数据并在稍后介绍的 Customer 实体实现中使用。

  1. 在 Visual Studio 解决方案资源管理器中,展开"CustomerModel"项目节点并右键单击"BdcModel1"节点。

  2. 选择"添加",然后单击"类"。"添加新项"对话框将出现,其中"类"模板将处于选中状态。

  3. 键入 Customer.cs 作为类文件的名称,然后单击"添加"以创建该类。Visual Studio 将在代码编辑器中打开 Customer.cs 文件。

  4. 将 Customer.cs 文件的内容替换为以下代码。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace CustomerModel.BdcModel1
    {
        public class Customer
        {
            public Int32 CustomerID { get; set; }
            public string CustomerName { get; set; }
        }
    }
  5. 保存对 Customer.cs 文件所做的更改。

将 Customer 实体添加到模型中

下面的步骤介绍如何将 Customer 实体添加到模型中以及如何将 CustomerID 标识符添加到实体中。

  1. 在 Visual Studio 中,选择"BdcModel1.bdcm"文件以显示"外部内容类型设计器"。

  2. 在 Visual Studio 的"视图"菜单上,单击"工具箱"。

  3. 从工具箱的"BusinessDataConnectivity"选项卡中,将一个实体拖动到"外部内容类型设计器"上。该新实体将显示在设计器上,并且 Visual Studio 会将一个文件添加到名为 EntityService.cs 的项目中。

  4. 在"视图"菜单上,单击"属性窗口"。

  5. 在"属性"窗口中,将新实体的"Name"属性设置为"Customer"。Visual Studio 将 EntityService.cs 文件重命名为 CustomerService.cs。

  1. 在外部内容类型设计器中,右键单击"Customer"实体,单击"添加",然后单击"标识符"。一个新的标识符将显示在该实体上。

  2. 在"属性"窗口中,将新标识符的名称更改为"CustomerID"。

  3. 在"类型名称"下拉列表中,选择"System.Int32"。

  4. 下图显示添加了 CustomerID 变量的 Customer 实体。

    图 6. 带有 CustomerID 变量的 Customer 实体


    带 CustomerID 变量的客户实体

将对 Microsoft.BusinessData 的引用添加到项目中

此直观操作方法提供的示例代码使用 Microsoft.BusinessData.dll 程序集所提供的 Microsoft.BusinessData.Runtime 命名空间中定义的异常。

  1. 在 Visual Studio 解决方案资源管理器中,选择"CustomerModel"项目。

  2. 在 Visual Studio 中,从"项目"菜单中选择"添加引用"。"添加引用"对话框将显示。

  3. 选择"浏览"选项卡并导航到以下文件夹:C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPIScroll,直至 Microsoft.BusinessData.dll 程序集可见,选择该程序集,然后单击"确定"。

    图 6a. 添加对 Microsoft.BusinessData 的引用


    添加对 Microsoft.BusinessData 的引用

将代码添加到外部内容类型中

下面的步骤介绍如何在"Customer"外部内容类型上实现 Finder、Specific Finder、Creator、Updater 和 Deleter 构造型或方法。

Business Data Connectivity (BDC) 共享服务调用 Finder 方法来请求 Customer 实体的列表。

添加 Finder 方法

添加 Finder 方法

  1. 在"Visual Studio 外部内容类型设计器"上,选择"Customer"实体。

  2. 在 Visual Studio 的"视图"菜单上,单击"其他窗口",然后单击"BDC 方法详细信息"。

  3. 在"BDC 方法详细信息"窗口中,从"添加方法"下拉列表中选择"创建 Finder 方法"。Visual Studio 将添加一个名为 ReadList 的方法、一个名为 customerList 的返回参数和一个名为 CustomerList 的类型描述符。

  4. 在"BDC 方法详细信息"窗口中,单击为 CustomerList 类型描述符显示的下拉列表,然后单击"编辑"。BDC 资源管理器将打开。BDC 资源管理器提供了模型的分层视图。

  5. 在"属性"窗口中,将 CustomerList 类型描述符的"Type Name"属性设置为 System.Collections.Generic.IEnumerable`1[CustomerModel.BdcModel1.Customer, BdcModel1]

  6. 在 BDC 资源管理器中,展开 CustomerList 类型描述符节点,并选择子 Customer 类型描述符节点。

  7. 在"属性"窗口中,将 Customer 类型描述符的"Type Name"属性设置为 CustomerModel.BdcModel1.Customer, BdcModel1

  8. 在 BDC 资源管理器中,右键单击 Customer 类型描述符节点,然后单击"添加类型描述符"。一个名为"TypeDescriptor"的新类型描述符将显示在 BDC 资源管理器中的 Customer 节点下。

  9. 在"属性"窗口中,将新类型描述符的"Name"属性设置为"CustomerID"。

  10. 将 CustomerID 类型描述符的"Type Name"属性设置为"System.Int32"。

  11. 使用下拉列表将 CustomerID 类型描述符的"Identifier"属性设置为"CustomerID"。

  12. 在 BDC 资源管理器中,右键单击 Customer 类型描述符节点,然后单击"添加类型描述符"。一个名为"TypeDescriptor"的新类型描述符将显示在 BDC 资源管理器中的 Customer 节点下。

  13. 在"属性"窗口中,将新类型描述符的"Name"属性设置为"CustomerName"。

  14. 下图显示在您添加 Finder 方法后模型的外观。

    图 7. 具有 Finder 方法的模型


    使用 Finder 方法建模

  15. 在"外部内容类型设计器"中的 Customer 实体上,双击 ReadList 方法。将在代码编辑器中打开 CustomerService.cs 文件。

  16. Customer 外部内容类型使用的 .NET Framework 程序集使用 Linq to XML 提供对 XML 数据文件中存储的数据的读/写访问。此外,如前所述,它还使用 Microsoft.BusinessData.Runtime 命名空间中定义的异常。将以下 using 语句添加到 CustomerService.cs 文件顶部,放置到您在 Visual Studio 中添加的 using 语句的下方。

    using System.Xml.Linq;using Microsoft.BusinessData.Runtime;
  17. 将以下变量声明添加到在 CustomerService.cs 文件中定义的 CustomerService 类中。使用 dataFilePath 变量指定包含客户数据的 XML 数据文件的位置。如果该数据文件不是在本节所示的文件夹中创建的,则更改 dataFilePath 变量的值以进行匹配。

    private const string dataFilePath = @"C:\Dev\Temp\CustomerData.xml";
  18. 将 CustomerService.cs 文件中的 ReadList 方法的定义替换为以下代码。

    public static IEnumerable<Customer> ReadList(){  try  {
        var customers =
          XElement.Load(dataFilePath).Elements("Customer");
        var customersList =
          from cust in customers
          orderby (string)cust.Attribute("ID")
          select new Customer
          {
            CustomerID = (Int32)cust.Attribute("ID"),
            CustomerName = (string)cust.Element("CustomerName")
          };
          return customersList;
      }
      catch (Exception generalException)
      {
        throw new RuntimeException(
          "There was a problem reading customer data.",
          generalException);  }}

添加 Specific Finder 方法

BDC 共享服务调用 Specific Finder 方法来请求特定 Customer 实体的数据。

  1. 在"外部内容类型设计器"中选择"Customer"实体。

  2. 在"BDC 方法详细信息"窗口中,从"添加方法"下拉列表中选择"创建 Specific Finder 方法"。Visual Studio 将添加一个名为 ReadItem 的方法、一个名为 customerID 的输入参数、一个名为 customer 的返回参数和两个分别名为 Customer 和 CustomerID 的类型描述符。

    下图显示在您添加 Specific Finder 方法后模型的外观。

    图 8. 具有 Specific Finder 方法的模型


    使用特定的 Finder 方法建模

  3. 在"外部内容类型设计器"中的 Customer 实体上,双击 ReadItem 方法。将在代码编辑器中打开 CustomerService.cs 文件。

  4. 将 CustomerService.cs 文件中的 ReadItem 方法的定义替换为以下代码。

    public static Customer ReadItem(int customerID)
    {
      try
      {
        var customers =
          XElement.Load(dataFilePath).Elements("Customer");
    
        var customerList =
          from cust in customers
          where (Int32)cust.Attribute("ID") == customerID
          select new Customer
          {
            CustomerID = (Int32)cust.Attribute("ID"),
            CustomerName = (string)cust.Element("CustomerName")
          };
    
          // The following will throw InvalidOperationException if the
          // customerNameElements collection is empty meaning a
          // customer with the specified ID does not exist.
          return customerList.First();
      }
      catch (InvalidOperationException )
      {
        throw new ObjectNotFoundException(
          "Unable to read data for the customer with ID = " +
          customerID.ToString() +
          ". The customer no longer exists.");
      }
      catch (Exception generalException)
      {
        throw new RuntimeException(
          "There was a problem reading customer data.",
          generalException);
      }
    }

添加 Creator 方法

BDC 共享服务调用 Creator 方法来创建新的 Customer 实体。

  1. 在"外部内容类型设计器"中选择"Customer"实体。

  2. 在"BDC 方法详细信息"窗口中,从"添加方法"下拉列表中选择"创建 Creator 方法"。Visual Studio 将添加一个名为 Create 的方法、一个名为 newCustomer 的输入参数、一个名为 returnCustomer 的返回参数和两个分别名为 NewCustomer 和 ReturnCustomer 的类型描述符。

  3. 在"BDC 方法详细信息"窗口中,单击为 Create 方法的 newCustomer 输入参数的 NewCustomer 类型描述符显示的下拉列表,然后单击"编辑"。这将选定 NewCustomer 类型描述符节点。

    在 BDC 资源管理器中,展开 NewCustomer 类型描述符节点,并选择子 CustomerID 类型描述符。在"属性"窗口中,将 CustomerID 类型描述符的"Creator Field"属性设置为"False"。这将阻止 BCS 在外部列表的新客户表单上为客户 ID 呈现用户界面控件。由于客户 ID 值由后端管理,并且不应由用户进行编辑,因此需要这样的设置。

    下图显示在您添加 Creator 方法后模型的外观。

    图 9. 具有 Creator 方法的模型


    使用 Creator 方法建模

  4. 在外部内容类型设计器中的 Customer 实体上,双击 Create 方法。将在代码编辑器中打开 CustomerService.cs 文件。

  5. 将 CustomerService.cs 文件中的 Create 方法的定义替换为以下代码。

    public static Customer Create(Customer newCustomer)
    {
      try
      {
        XElement customers = XElement.Load(dataFilePath);
        Int32 nextCustomerId =
          (Int32)customers.Attribute("NextCustomerId");
    
        Customer returnCustomer = new Customer();
    
        returnCustomer.CustomerID = nextCustomerId;
        returnCustomer.CustomerName = newCustomer.CustomerName;
    
        XElement newCustomerElement = new XElement("Customer");
        newCustomerElement.SetAttributeValue("ID", nextCustomerId);
    
        XElement newCustomerNameElement = new XElement("CustomerName",
          returnCustomer.CustomerName);
    
        newCustomerElement.Add(newCustomerNameElement);
        customers.Add(newCustomerElement);
    
        customers.SetAttributeValue("NextCustomerId",
          nextCustomerId + 1);
        customers.Save(dataFilePath);
    
        return returnCustomer;
      }
      catch (Exception generalException)
      {
        throw new RuntimeException(
          "There was a problem creating a new customer.",
          generalException);
      }
    }

添加 Updater 方法

BDC 共享服务调用 Updater 方法来编辑现有的 Customer 实体。

  1. 在外部内容类型设计器上,选择 Customer 实体。

  2. 在"BDC 方法详细信息"窗口中,从"添加方法"下拉列表中选择"创建 Updater 方法"。Visual Studio 将添加一个名为 Update 的方法、一个名为 customer 的输入参数和一个名为 Customer 的类型描述符。

  3. 在"BDC 方法详细信息"窗口中,将另一个输入参数添加到 Update 方法中。将新参数的"Name"属性设置为"customerID"。选择新参数的类型描述符。在"属性"窗口中,将"Name"属性设置为"CustomerID",将"Type Name"属性设置为"System.Int32",并将"Pre-Updater"属性设置为"True"。

    下图显示在您添加 Updater 方法后模型的外观。

    图 10. 具有 Updater 方法的模型


    使用 Updater 方法建模

  4. 在外部内容类型设计器中的 Customer 实体上,双击 Update 方法。将在代码编辑器中打开 CustomerService.cs 文件。

  5. 将 CustomerService.cs 文件中的 Update 方法的定义替换为以下代码。

    public static void Update(Customer customer, Int32 customerID)
    {
      try
      {
        XElement customers = XElement.Load(dataFilePath);
    
        var customerNameElements =
          from cust in customers.Elements("Customer")
          where (Int32)cust.Attribute("ID") == customer.CustomerID
          select cust.Element("CustomerName");
    
        // The following will throw InvalidOperationException if
        // the customerNameElements collection is empty meaning a
        // customer with the specified ID does not exist.
        XElement customerNameElement = customerNameElements.First();
        customerNameElement.SetValue(customer.CustomerName);
    
        customers.Save(dataFilePath);
      }
      catch (InvalidOperationException)
      {
        throw new ObjectNotFoundException(
          "Unable to update the customer with ID = " +
          customerID.ToString() +
          ". The customer no longer exists.");
      }
      catch (Exception generalException)
      {
        throw new RuntimeException(
          "There was a problem updating the customer with ID = " +
          customerID.ToString() + ".", generalException);
      }
    }

读取

此直观操作方法提供了一些步骤和示例代码,它们演示如何创建一个使用 .NET Framework 程序集的 BCS 外部内容类型,该程序集可以对 XML 数据文件执行读/写操作。本节使用此处提供的示例代码中的代码段来描述此直观操作方法所采用的方法。

Finder 方法实现

BDC 共享服务使用 Finder 方法来返回实体列表。在此处所示的演练中,当 SharePoint 在外部列表中显示客户项列表时,会调用 Customer 实体的 Finder 方法。在之前提供的示例代码中,Customer 实体的 Finder 方法由 CustomerService.ReadList 方法实现。

ReadList 方法首先打开 XML 数据文件并获取 Customer 元素的集合。

var customers = XElement.Load(dataFilePath).Elements("Customer");

然后,它创建并返回从每个 Customer 元素创建的 Customer 对象的集合。

var customersList =  from cust in customers
  orderby (string)cust.Attribute("ID")
  select new Customer
  {    CustomerID = (Int32)cust.Attribute("ID"),
    CustomerName = (string)cust.Element("CustomerName")
  };return customersList;

Specific Finder 方法实现

BDC 共享服务使用 Specific Finder 方法来返回特定实体实例。在此处所示的演练中,当您选择编辑或查看外部列表中的客户项时,将调用 Customer 实体的 Specific Finder 方法。在之前提供的示例代码中,Customer 实体的 Specific Finder 方法由 CustomerService.ReadItem 方法实现。

ReadItem 方法接受 Int32 参数,该参数表示所请求的客户实例的唯一 ID。

public static Customer ReadItem(int customerID)

ReadItem 方法首先打开 XML 数据文件并获取 Customer 元素的集合。

然后,它从其 ID 属性等于传递给此方法的客户 ID 的每个 Customer 元素创建 Customer 对象的集合。由于客户 ID 是唯一的,该集合应只包含一个客户,因此,此方法返回该集合中的第一项。

var customerList =
    from cust in customers
    where (Int32)cust.Attribute("ID") == customerID
    select new Customer
    {
      CustomerID = (Int32)cust.Attribute("ID"),
      CustomerName = (string)cust.Element("CustomerName")
    };

  return customerList.First();

Creator 方法实现

BDC 共享服务调用 Creator 方法来创建新的实体实例。在之前所示的演练中,当您向外部列表中添加新客户项时,将调用 Customer 实体的 Creator 方法。在提供的示例代码中,Customer 实体的 Creator 方法由 CustomerService.Create 方法实现。

Create 方法接受一个 Customer 参数,该参数表示通过外部列表的新项表单输入的客户数据。

public static Customer Create(Customer newCustomer)

Create 方法首先打开 XML 数据文件并获取顶级 Customers 元素,然后从 NextCustomerId 属性中读取要用于新客户的 ID 值。

XElement customers = XElement.Load(dataFilePath);
Int32 nextCustomerId =
  (Int32)customers.Attribute("NextCustomerId");

此方法将新建一个 Customer 对象并将其 CustomerID 属性设置为所读取的值,并且将该对象的 CustomerName 属性设置为传递给此方法的 Customer 对象的 CustomerName 属性值。

Customer returnCustomer = new Customer();

returnCustomer.CustomerID = nextCustomerId;
returnCustomer.CustomerName = newCustomer.CustomerName;

接下来,此方法创建新的 Customer 和 CustomerName 元素,设置这两个元素的 Customer ID 属性和 CustomerName 值,并将这两个元素添加为顶级 Customers 元素。

XElement newCustomerElement = new XElement("Customer");
newCustomerElement.SetAttributeValue("ID", nextCustomerId);

XElement newCustomerNameElement = new XElement("CustomerName",
  returnCustomer.CustomerName);

newCustomerElement.Add(newCustomerNameElement);
customers.Add(newCustomerElement);

最后,递增 NextCustomerId 属性的值,并将所有更改保存回 XML 数据文件。

customers.SetAttributeValue("NextCustomerId", nextCustomerId + 1);
customers.Save(dataFilePath);

Updater 方法实现

BDC 共享服务调用 Updater 方法来编辑现有的实体实例。在此处所示的演练中,当用户编辑外部列表中的客户项时,将调用 Customer 实体的 Updater 方法。在之前提供的示例代码中,Customer 实体的 Updater 方法由 CustomerService.Update 方法实现。

Update 方法接受一个 Customer 参数(表示用户通过外部列表的编辑项表单输入的客户数据)和一个 Int32 参数(表示要更新的客户的唯一 ID)。

public static void Update(Customer customer, Int32 customerID)

Update 方法首先打开 XML 数据文件并获取顶级 Customers 元素。

XElement customers = XElement.Load(dataFilePath);

然后,它从其 ID 属性等于传递给此方法的客户 ID 的每个 Customer 元素创建 Customer 对象的集合。

var customerNameElements =
  from cust in customers.Elements("Customer")
  where (Int32)cust.Attribute("ID") == customer.CustomerID
  select cust.Element("CustomerName");

由于客户 ID 是唯一的,该集合应只包含一个客户,因此,此方法会获取该集合中的第一项并将其值设置为传递给此方法的 Customer 对象的 CustomerName 属性值。最后,将所有更改保存回 XML 数据文件。

XElement customerNameElement = customerNameElements.First();
customerNameElement.SetValue(customer.CustomerName);

customers.Save(dataFilePath);

Deleter 方法实现

BDC 共享服务调用 Deleter 方法来删除现有的实体实例。在此处所示的演练中,当用户删除外部列表中的客户项时,将调用 Customer 实体的 Deleter 方法。在之前提供的示例代码中,Customer 实体的 Deleter 方法由 CustomerService.Delete 方法实现。

Delete 方法接受一个 Int32 参数,该参数表示要删除的客户的唯一 ID。

public static void Delete(int customerID)

Delete 方法首先打开 XML 数据文件并获取顶级 Customers 元素。

XElement customers = XElement.Load(dataFilePath);

然后,它从其 ID 属性等于传递给此方法的客户 ID 的每个 Customer 元素创建 Customer 对象的集合。

var customerElements =
  from cust in customers.Elements("Customer")
  where (Int32)cust.Attribute("ID") == customerID
  select cust;

由于客户 ID 是唯一的,该集合应只包含一个客户,因此,此方法将获取该集合中的第一项并删除它。最后,将所有更改保存回 XML 数据文件。

XElement customer = customerElements.First();
customer.Remove();

customers.Save(dataFilePath);
观看

观看视频

观看视频(该链接可能指向英文页面)

长度:25:12 | 大小:28.6 MB | 类型:WMV

单击以获取代码

获取代码(该链接可能指向英文页面)

浏览