問題的來源請參考gattaca的留言,雖然問題狠簡單,但是對於不熟悉ClientaDataSet的人來說,還是值得研究的。本例將實現一個基於.NET的WebService,並且使用Delphi調用,獲取數據。
首先開發一個WebService,我使用VS2008下C#語言進行開發,新建一個ASP.NET Web Service工程,代碼如下: [WebMethod] public string GetData() { string ConnStr = "Provider=SQLOLEDB.1;Password=\"\";Persist Security Info=True;User ID=sa;Initial Catalog=Northwind;Data Source=192.168.1.100"; OleDbConnection myConnection = new OleDbConnection(ConnStr); string strSQL = "select * from Employees"; OleDbDataAdapter myAdapter = new OleDbDataAdapter(strSQL, myConnection); DataSet ds = new DataSet(); myAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey; myAdapter.Fill(ds, "Employees");
return CSDS2DDS.ToClientDataSet(ds, "Employees"); }
其中CSDS2DDS是CSharpDataSetToDelphiDataSet的縮寫,它包含一個靜態方法,用於將.NET的數據集轉換為ClientDataSet所使用的XML。這個類的代碼如下: public class CSDS2DDS { public CSDS2DDS() { }
public static string ToClientDataSet(DataSet ds, string TableName) { int FieldCount = ds.Tables[TableName].Columns.Count; string result = "<?xml version=\"1.0\" standalone=\"yes\"?>"; result += "<DATAPACKET Version=\"2.0\">"; result += "<METADATA><FIELDS>"; for (int i = 0; i < FieldCount; i++) { DataColumn dc = ds.Tables[TableName].Columns[i]; string FieldType = dc.DataType.Name.ToLower(); // integer if (FieldType.ToLower() == "int32") FieldType = "i4"; // int64 if (FieldType.ToLower() == "int64") FieldType = "i8"; // float if (FieldType.ToLower() == "single") FieldType = "r8"; // memo if (FieldType.ToLower() == "string" && dc.MaxLength > 255) FieldType = "bin.hex"; // bytes if (FieldType.ToLower() == "byte[]") FieldType = "bin.hex"; result += string.Format("<FIELD attrname=\"{0}\" fieldtype=\"{1}\" ", dc.ColumnName, FieldType); if (FieldType == "bin.hex" && dc.DataType.Name.ToLower() == "string") result += "SUBTYPE=\"Text\" "; else if (FieldType == "string") result += string.Format("WIDTH=\"{0}\" ", dc.MaxLength); else if (FieldType == "sqldatetime") result += "SUBTYPE=\"Formatted\""; else if (FieldType == "bin.hex" && dc.DataType.Name.ToLower() != "string" || dc.DataType.Name.ToLower() == "byte[]") result += "SUBTYPE=\"Binary\""; result += "/>"; } result += "</FIELDS><PARAMS/></METADATA>"; result += "<ROWDATA>"; int RowCount = ds.Tables[TableName].Rows.Count; for (int i = 0; i < RowCount; i++) { result += "<ROW RowState=\"4\" "; for (int j = 0; j < FieldCount; j++) { DataTable dt = ds.Tables[TableName]; string value = dt.Rows[i].ItemArray[j].ToString(); value = value.Replace("\"", """); result += string.Format("{0}=\"{1}\" ", dt.Columns[j].ColumnName, value); } result += "/>"; } result += "</ROWDATA></DATAPACKET>"; return result; } } 這個類非常明確,就是用循環的方式讀出.NET數據集中的數據,並且拼裝成ClientDataSet使用的XML 做完這一步,就可以將WebService部署去IIS,然後用Delphi直接調用了,用WSDL Importer或RO引入WSDL,生成單元後就可以調用它。 procedure TForm1.FormCreate(Sender: TObject); var xml: string; begin xml := Service.GetServiceSoap.GetData; ClientDataSet1.XMLData := xml; ClientDataSet1.Open; end; 程序執行後即可看到,數據從.NET端傳遞到了Delphi端。 由於轉換的代碼直接讀取.NET的數據集,因此對delphi端沒有任何影響。 如果以後.NET的數據集發生了改變,也只需要在服務器上直接修改轉換代碼,.NET數據集的格式改變的可能性非常小。至少從.NET1.1開始,到現在的.NET3.5,它完全沒有改變過。 注意:部署WebService時請使用IIS6.0,盡量使用Windows2003,如果用XP,可能會產生不可預知的問題。
转载于:https://www.cnblogs.com/bennylam/archive/2009/11/19/1605791.html