.NET通過RFC讀取SAP數據


  本篇文章中我主要講的是.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     }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM