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

LINQ to SAP

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (28投票s)

2012年4月2日

CPOL

8分钟阅读

viewsIcon

97632

如何使用 LINQ 连接到 SAP/R3 系统。

引言

自第一个预览版本发布以来,关于微软新的数据访问技术 LINQ (Language Integrated Query) 已经有很多文章。但 LINQ 及其可扩展性仍有一些有趣的方面。本文将介绍一个名为 LINQ to SAP 的新提供程序,它提供了一种简单的方式来在 .NET 应用程序中检索 SAP/R3 系统中的业务数据。

随着 .NET Framework 3.5 的推出以及 C# 和 VB.NET 的编程语言扩展,微软开始重新定义开发人员实现数据访问的方式。如今,几乎所有应用程序都需要查询来自不同数据源的数据。这些数据源主要是 SQL 数据库、XML 文件或内存集合。LINQ 提供了一种通用且标准化的方法,可以使用特殊的数据提供程序访问所有这些数据源。LINQ 的语法在很大程度上类似于 SQL。下面的示例展示了如何使用 LINQ 查询字符串数组中的数据。

string[] names = {"John", "Patrick", "Bill", "Tom"}

var res = from n in names where n.Contains("o") select n;

foreach(var name in res)
  Console.WriteLine(name); 

这个简单的 LINQ 查询基于内存集合(数组),它选择数组 names 中包含字母“o”的所有项。控制台输出:John, Tom。LINQ 介绍超出了本文的范围。您可以在 CodeProject.com 上找到一篇非常好的介绍性文章。

LINQ 提供程序

.NET Framework 附带了用于集合和列表(LINQ to Objects)、Microsoft SQL Server 数据库(LINQ to SQL)、XML 文件(LINQ to XML)以及 DataSet 对象实例(LINQ to DataSet)的内置提供程序。除了标准提供程序之外,开发人员还可以通过创建自定义提供程序来扩展 LINQ,以支持特殊的数据源。LINQ to LDAP 或 LINQ to Amazon 就是此类自定义提供程序的示例。

要编写自定义 LINQ 提供程序,基本上必须实现两个接口:`IQueryable` 和 `IQueryProvider`。这些接口使得对象在 LINQ 表达式中可查询。开发 LINQ 提供程序可能是一项非常复杂的任务,但网上有许多优秀的博客文章详细解释了相关步骤。

本文将介绍 Theobald Software 公司的一个新提供程序,名为 LINQ to SAP,它为开发人员提供了一种简单的方式来访问 SAP/R3 系统及其数据对象。该软件还提供了一个 Visual Studio 2008 设计器,用于交互式地定义 SAP 对象并将其集成到 .NET 应用程序中。

SAP 背景

本节将简要解释和介绍 LINQ to SAP 可以查询的 SAP 对象。最重要的对象是函数模块、表、BW Cube 和查询。

函数模块基本上类似于传统编程语言中的普通过程。函数模块是用 ABAP(SAP 编程语言)编写的,可以在 SAP/R3 系统内的任何其他程序中访问。它们接受导入和导出参数以及其他特殊参数。下图显示了 SAP 工作台中一个名为 BAPI_EQUI_GETLIST 的函数模块的示例。

LINQtoSAP/Function_Figure1.jpg

此外,BAPI(业务应用程序接口)是组织在 SAP 业务对象存储库中的特殊函数模块。LINQ to SAP 还允许访问 SAP 表。这些基本上是直接的关系数据库表。此外,LINQ to SAP 设计器允许开发人员定义和访问 BW Cube(业务 Cube)和查询(SAP Query)。BW Cube 也称为 OLAP Cube。数据在 Cube 中以多维方式组织。SAP Query 的工作方式与其他查询类似。要唯一标识一个 SAP Query,需要三个信息:用户区域(全局或本地)、用户组和查询名称。通过 Query 的概念,SAP 提供了一种无需了解 SAP ABAP 编程语言即可轻松生成报表的方法。

LINQ to SAP 的 Visual Studio 2008 设计器

为了使用 LINQ to SAP 和相关的 Visual Studio 设计器,必须首先安装 Theobald Software 的 .NET 库 ERPConnect.net。该软件是 .NET 和 SAP/R3 系统之间的基本构建块,并提供了一个简单的 API 来在两个系统之间交换数据。该公司提供免费试用版下载。安装 ERPConnect.net 后,必须使用安装程序(参见手册)单独安装 LINQ to SAP。该提供程序和设计器实际上是 ERPConnect.net 库的扩展。LINQ to SAP 提供程序本身由 Visual Studio 2008 设计器和包含在 ERPConnect.Linq 命名空间中的其他类库组成。

安装程序会向 Visual Studio 2008 添加一种新的项目项类型,文件扩展名为 .erp,并将其与设计器关联。双击 .erp 文件将打开 LINQ to SAP 设计器。该设计器通过自动生成源代码来集成 SAP 对象,来支持应用程序开发人员。对于 .erp 文件中定义的所有 SAP 对象,提供程序将创建一个继承自 ERPDataContext 基类的上下文类。生成的上下文类包含表示已定义 SAP 对象的方法和子类。除了 .erp 文件之外,LINQ to SAP 设计器还将相关的自动生成源代码保存在一个扩展名为 .Designer.cs 的文件中。

LINQtoSAP/NewProject_Figure2.jpg

LINQtoSAP/SAPObjects_Figure3.jpg

LINQtoSAP/Connection_Figure4.jpg

函数模块

本节展示了如何通过创建 LINQ to SAP 对象来访问和获取数据,使用函数模块 BAPI_EQUI_GETLIST。该模块返回预定义工厂的设备列表。首先,必须将一个新的 LINQ to SAP 文件(.erp)添加到新的或现有的 Visual Studio 2008 项目中。通过打开 .erp 文件,LINQ to SAP 设计器将启动。通过双击 Visual Studio 工具箱中的 Function 项,将添加一个新的 SAP 对象函数模块。在下一步中,将打开对象搜索对话框,开发人员可以搜索函数模块。

LINQtoSAP/Search_Figure5.jpg

选择完成后,LINQ to SAP 设计器将显示函数模块对话框,其中包含所选模块 BAPI_EQUI_GETLIST 的所有数据、属性和参数定义。用户现在可以更改自动生成方法的命名以及所有使用的参数。

LINQtoSAP/Dialog_Figure6.jpg

对于每个函数模块,LINQ to SAP 设计器将生成一个上下文类方法,以及所有附加的对象类和结构。例如,如果用户为函数模块 BAPI_EQUI_GETLIST 定义了一个名为 GetEquipmentList 的方法名,则设计器将生成一个具有该名称和已定义方法签名的上下文类方法。用户还可以指定要交换的参数。对话框的下部显示了 SAP 典型参数,如 IMPORT、EXPORT、CHANGING 和 TABLES 参数。LINQ to SAP 允许为 SAP 参数定义默认值。这些参数也可以用作自动生成的上下文类方法以及返回值的参数。参数和相关结构的名称也可以重命名。

上述函数模块的方法签名如下所示:

public EquipmentTable GetEquipmentList(PlantTable plants)

上下文类本身默认命名为 SAPContext。上下文类名称、命名空间、连接设置以及其他标志可以在 LINQ to SAP 设计器的属性窗口中定义。以下代码显示了如何使用上下文类 SAPContext:

class Program
{
  static void Main()
  {
    SAPContext dc = new SAPContext("TESTUSER", "XYZ");

    SAPContext.PlantTable plants = new SAPContext.PlantTable();
    SAPContext.PlantStructure ps = plants.Rows.Add();
    ps.SIGN = "I";
    ps.OPTION = "EQ";
    ps.LOW = "3000";

    SAPContext.EquipmentTable equipList = dc.GetEquipmentList(plants);
  }
}

表格

添加 SAP 表的过程基本上与添加函数模块(参见上文)相同。在 Visual Studio 中从工具箱添加 SAP 表对象并使用搜索对话框找到表后,将显示表对话框:

LINQtoSAP/Tables_Figure7.jpg

在表对话框的上部,用户必须为自动生成的文件定义表对象的类名。默认名称是表的名称。下部显示一个数据网格,其中包含所有表字段及其定义。对于每个字段,都可以为主类自动生成的上下文类代码定义一个类属性名。第一个列中的复选框用于选择该字段是否将包含在表类中。

上图显示了 SAP 表对象 T001W 的定义。该表存储工厂信息。该类未被更改,因此设计器将创建一个名为 T001W 的 C# 类。此外,上下文类将包含一个 T001WList 属性。此属性的类型为 ERPTable<T001W>,这是一个 LINQ 可查询的数据类型。

以下代码显示了如何使用上下文类查询表 T001W:

class Program
{
  static void Main()
  {
     SAPContext dc = new SAPContext("TESTUSER", "XYZ");
     dc.Log = Console.Out;

     var res = from p in dc.T001WList
               where p.WERKS == "3000"
               select p;

     foreach (var item in res)
       Console.WriteLine(item.NAME1);
  }
}

SAP 上下文类和日志记录

要使用 LINQ to SQL 访问对象,提供程序将生成一个名为 DataContext 的上下文类。同样,LINQ to SAP 也创建一个名为 SAPContext 的上下文类。此类被定义为部分类。部分类是一种类型声明,可以分布在多个源文件中,因此开发人员可以轻松地扩展自动生成的类,如 LINQ to SAP 的上下文类。

以下代码示例显示了如何添加一个部分类(文件 SAPContext.cs),该类添加了一个名为 GetEquipmentListForMainPlant 的新自定义方法,以扩展 LINQ to SAP 设计器生成的上下文类。此新方法内部调用自动生成的 GetEquipmentList 方法,并提供预定义的参数值。C# 编译器将在内部合并自动生成的 LINQtoERP1.Designer.cs 和 SAPContext.cs 源文件。

using System;

namespace LINQtoSAP
{
  partial class SAPContext
  {
    public EquipmentTable GetEquipmentListForMainPlant()
    {
      SAPContext.PlantTable plants = new SAPContext.PlantTable();
      SAPContext.PlantStructure ps = plants.Rows.Add();
      ps.SIGN = "I";
      ps.OPTION = "EQ";
      ps.LOW = "3000";
      
      return GetEquipmentList(plants);
    }
  }
}

LINQ to SAP 还提供了记录 LINQ 查询翻译的功能。为了记录数据,必须将上下文类的 LOG 属性设置为 TextWriter 实例,例如控制台输出 Console.Out。LINQ to SAP 所做的只是一个非常基础的日志记录,仅限于表对象。但它可以帮助开发人员了解翻译后的 where 子句是什么样的。

摘要

总而言之,LINQ to SAP 是一个非常简单但又强大的 LINQ 数据提供程序和 Visual Studio 2008 设计器。您还可以体验如何使用 .NET 对 SAP/R3 系统进行开发。有关该产品的更多信息,请访问供应商的首页:http://www.theobald-software.com。

© . All rights reserved.