本篇文章中我主要讲的是.NET如何通过RFC从SAP中读取数据。为了功能的可复用性,我将调用RFC的代码从业务层中分离出来单独建立在一个namespace中。
当然除了需要我们自己编写代码以外,还需要引用SAP提供的程序集文件(sapnco.dll、sapnco_utils.dll),在代码文件需要引用相应的命名空间(using
SAP.Middleware.Connector;)。
我在这个namespace中建立了三个类来实现这个功能,一个配置类(RfcDestinationConfig)、一个参数类(RfcParam)、一个主体功能类(RfcManager)。
- RfcDestinationConfig
我们需要一个类来实现SAP的连接配置工作,就如同为数据连接层建立一个数据库配置类一样重要。
1 public class RfcDestinationConfig : IDestinationConfiguration
2 {
3 #region 事件
4 /// <summary>
5 /// 配置变更事件
6 /// </summary>
7 public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;
8 /// <summary>
9 /// 默认接收器名称
10 /// </summary>
11 public static readonly string DefaultDesName = "destination";
12 #endregion
13
14 #region 方法
15 /// <summary>
16 /// 配置变更事件触发时,暂时无用
17 /// </summary>
18 /// <param name="destinationName"></param>
19 /// <param name="args"></param>
20 public void OnConfigurationChanged(string destinationName, RfcConfigurationEventArgs args)
21 {
22 if (ConfigurationChanged != null)
23 {
24 ConfigurationChanged(destinationName, args);
25 }
26 }
27
28 /// <summary>
29 /// 获取SAP配置参数
30 /// </summary>
31 /// <param name="destinationName"></param>
32 /// <returns></returns>
33 public RfcConfigParameters GetParameters(string destinationName)
34 {
35 if (destinationName == DefaultDesName)
36 {
37 RfcConfigParameters parms = new RfcConfigParameters();
38 parms.Add(RfcConfigParameters.AppServerHost,ConfigManager.GetAppSettings("SAPApplicationServer").Trim()); //SAP主机IP
39 parms.Add(RfcConfigParameters.SystemNumber, ConfigManager.GetAppSettings("SAPSystemNumber").Trim()); //SAP实例
40 parms.Add(RfcConfigParameters.User, ConfigManager.GetAppSettings("SAPUser").Trim()); //用户名
41 parms.Add(RfcConfigParameters.Password,ConfigManager.GetAppSettings("SAPPwd").Trim()); //密码
42 parms.Add(RfcConfigParameters.Client, ConfigManager.GetAppSettings("SAPClient").Trim()); // Client
43 parms.Add(RfcConfigParameters.Language,ConfigManager.GetAppSettings("SAPLanguage").Trim()); //登陆语言
44 return parms;
45 }
46 else
47 {
48 return null;
49 }
50 }
51
52 /// <summary>
53 /// 变更事件方法,暂时无用
54 /// </summary>
55 /// <returns>true</returns>
56 public bool ChangeEventsSupported()
57 {
58 return true;
59 }
60 #endregion
61 }
- RfcParam
想要从SAP中读取数据,就必须将查询条件作为参数传递给RFC。另外为了返回的结果具有通用性,我使用DataTable作为返回结果的类型,然后考虑到不同条件下列是不同的,我又将列也参数化,最终我将输入参数和输出参数都封装在一个参数类之中。
1 public class RfcParam
2 {
3 /// <summary>
4 /// 初始化
5 /// </summary>
6 public RfcParam()
7 {
8 CoulmnNames = new List<string>();
9 Param = new Dictionary<string, object>();
10 }
11 /// <summary>
12 /// RFC方法名称
13 /// </summary>
14 public string RfcName { get; set; }
15 /// <summary>
16 /// RFC表名
17 /// </summary>
18 public string TableName { get; set; }
19 /// <summary>
20 /// 数据表各列的列名
21 /// </summary>
22 public List<string> CoulmnNames { get; set; }
23 /// <summary>
24 /// RFC执行参数
25 /// </summary>
26 public Dictionary<string, object> Param { get; set; }
27 }
- RfcManager
该主角登场了,读取数据的功能正是业务层真正想要的东西。
方法ExecRfc首先将输出参数转换成一个真正可用的新的DataTable,然后将输入参数传递给SAP执行相关的RFC功能并返回IRfcTable(SAP定义的一种接口),最后再将IRfcTable转换成我们自定义的DataTable。
1 public class RfcManager
2 {
3 #region 属性字段
4 /// <summary>
5 /// 接收器
6 /// </summary>
7 public RfcDestination Prd { get; set; }
8 /// <summary>
9 /// 数据仓库
10 /// </summary>
11 public RfcRepository Repo { get; set; }
12 #endregion
13
14 #region 构造函数
15 /// <summary>
16 /// 初始化
17 /// </summary>
18 public RfcManager()
19 {
20 //初始化RFC接收器
21 //配置接收器
22 IDestinationConfiguration IDC = new RfcDestinationConfig();
23 //注册
24 RfcDestinationManager.RegisterDestinationConfiguration(IDC);
25 //获取RFC接收器
26 this.Prd = RfcDestinationManager.GetDestination(RfcDestinationConfig.DefaultDesName);
27 this.Repo = this.Prd.Repository;
28 //注销
29 RfcDestinationManager.UnregisterDestinationConfiguration(IDC);
30 }
31 #endregion
32
33 #region 方法
34 /// <summary>
35 /// 执行RFC获取数据表
36 /// </summary>
37 /// <param name="rfcname">rfc方法名称</param>
38 /// <param name="tablename">rfc表名</param>
39 /// <param name="columnnames">数据表列名列表</param>
40 /// <param name="param">rfc执行参数</param>
41 /// <returns>数据表</returns>
42 public DataTable ExecRfc(string rfcname, string tablename, List<string> columnnames, Dictionary<string, object> param)
43 {
44 DataTable dt = new DataTable();
45
46 if (columnnames != null && columnnames.Count > 0)
47 {
48 //配置datatable
49 dt.Columns.Clear();
50 foreach (string cname in columnnames)
51 {
52 dt.Columns.Add(cname, typeof(string));
53 }
54 dt.AcceptChanges();
55
56 //从SAP那获取数据表
57 if (!string.IsNullOrEmpty(rfcname) && param != null && param.Count > 0)
58 {
59 IRfcFunction rfc = this.Repo.CreateFunction(rfcname);
60 foreach (KeyValuePair<string, object> kv in param)
61 {
62 rfc.SetValue(kv.Key, kv.Value);
63 }
64 rfc.Invoke(this.Prd);
65 IRfcTable iTable = rfc.GetTable(tablename);
66 if (iTable.Count > 0)
67 {
68 for (int i = 0; i < iTable.RowCount; i++)
69 {
70 iTable.CurrentIndex = i;
71 DataRow oNewRow = dt.NewRow();
72 foreach (string cname in columnnames)
73 {
74 oNewRow[cname] = iTable.GetString(cname).ToString();
75 }
76 dt.Rows.Add(oNewRow);
77 }
78 }
79 }
80 }
81
82 return dt;
83 }
84 #endregion
85 }
.NET通过RFC读取SAP数据,布布扣,bubuko.com
时间: 2024-10-13 12:02:08