一切都是空的,除了Money,只有需求才是最真的,你懂的。sql
最近接到個略顯棘手的需求,思索再三,想出兩種方法,可以爲都不太好,這裏與你們討論一下。數據庫
需求以下:數組
用戶須要在現有的某個grid中添加新的一列: Des。現有grid的全部數據DataTable:OraDt都來自一個oracle數據庫,而新加的Des值卻來自別的四個sqlserver數據庫中的某一個。四個SqlServer數據庫CHNDB,JPNDB,USDB,CANDB的結構相同,只是數據不一樣。oracle
根據兩個變量:geo和desID能夠從前面sql DB中中獲得Des的值。geo肯定從哪一個sql數據庫中獲取,desID用來獲得des的值。 geo和desID就在OraDt中存着,如何才能高效的獲取des的值?sqlserver
geo與sqlserver db對應關係以下:性能
Geo值 | Sqlserver DB |
CHN | CHNDB |
JPN | JPNDB |
US | USDB |
CAN | CANDB |
//獲得oracle datatable,添加row[des],遍歷datatable,獲取des的值,更新des protected void ProcessDataTable() { //添加新列 _ds.Tables[0].Columns.Add(new DataColumn("Des", typeof(string))); string desID = string.Empty; string geo = string.Empty; //遍歷OraDt foreach (DataRow row in _ds.Tables[0].Rows) { if (row["desID"] != DBNull.Value) desID = row["desID"].ToString(); if (!string.IsNullOrEmpty(desID) ) { //獲得geo switch (row["countryId"].ToString()) { case Country.US: geo = "US"; break; case Country.China: geo = "CHA"; break; case Country.Canada: geo = " CAN"; break; case Country.Jpan: geo = "JPN"; break; } //獲得添加des row["Des"]= GetExemptionDes(geo, desID); } else row["Des"] = string.Empty; } }
GetExemptionDes的代碼:spa
private string GetExemptionDes(string geo, string desid) { string description = string.Empty; string query = "select des from taxDes where desid="+desid; //肯定哪一個DB獲取數據 Database DbGEO = DbGEOFactory.CreateDatabase(geo); System.Data.Common.DbCommand sqlCmd = DbGEO.GetSqlStringCommand(query); //得到des值 using (IDataReader dr = DbGEO.ExecuteReader(sqlCmd)) { while (dr.Read()) { if (dr["des"] != null) description = dr["des"].ToString(); } dr.Close(); } return description; }
這種想法思路簡單,問題也顯而易見,雖然一般狀況下OraDt只有十幾個row,可極個別時候OraDt的row能達到上千個,這時候,上面的方法要連續訪問 Sqlserver DB上千次,顯然嚴重影響了性能。有某有其餘的好方法呢?調試
因爲geo最多隻有四個,因此咱們能夠把相同geo下的desID拼接起來,最後一塊訪問sqlserver db,這樣最多隻須要訪問四次,思路:code
前三步與上面方法同樣,server
4.根據geo把desid拼接於一個string變量中
5.最後一塊兒訪問sqlserver db
6.得到des值,
7.OraDt更新des
第二方法缺憾:
大量datatable的操做實際上也影響了代碼的效率,並且OraDt的數據量一般只有幾十行,用這種方法處理普通的OraDt時候顯然太過繁瑣。
但是如今看來彷佛只有這兩種方法來解決這個問題了,難道真的就由這麼個性能問題存在於咱們的代碼中麼?哪位若是有什麼新的解決思路,能夠一塊兒分享一下,一塊兒進步。
第一種方法和第二種到底用哪種好呢?
現將第二方案的詳細代碼列示以下,因爲寫的匆忙,還將來的及調試,有什麼問題或者哪裏能夠改進,但願你們多多指正。
能夠看到這種方法繁瑣操縱OraDt,尤爲是在方法UpdateOraDT中,因爲某種緣由不能使用Linq 來鏈接datatable,三個foreach 嵌套起來簡直不堪入目。處理普通的OraDt時候明顯會帶來性能問題:
protected void ProcessDataTable() { _ds.Tables[0].Columns.Add(new DataColumn("ExemptionDes", typeof(string))); string desID = string.Empty; string geo = string.Empty; //建造一個鋸齒數組,[0]:geo,[1]: 該geo是否須要被訪問,默認0表示不須要,[3]用來拼接desID string[][] geoExistArray = new string[4][] { new string[] { "NA", "0","" }, new string[] { "LA", "0","" }, new string[] { "EMEA", "0","" }, new string[] { "AP", "0","" }, }; //遍歷datatable foreach (DataRow row in _ds.Tables[0].Rows) { if (row["desID"] != DBNull.Value) { xmtn_ID = row["desID"].ToString(); } //若是desID爲空,直接將des設置爲0 //不爲空,則遍歷datatable,取des值 if (!string.IsNullOrEmpty(desID)) { switch (row["countryId"].ToString()) { case Country.US: geo = "US"; geoExistArray[0][0] = "1"; geoExistArray[0][2] = geoExistArray[0][2] + desID+ ","; break; case Country.China: geo = "CHN"; geoExistArray[1][0] = "1"; geoExistArray[1][2] = geoExistArray[1][2] + desID+ ","; break; case Country.Canada: geo = "CAN"; geoExistArray[2][0] = "1"; geoExistArray[2][2] = geoExistArray[2][2] + desID+ ","; break; case Country.Jpan: geo = "JPN"; geoExistArray[3][0] = "1"; geoExistArray[3][2] = geoExistArray[3][2] + desID+ ","; break; } } else row["Des"] = string.Empty; } //移除每一個拼出的desID字符串中的最後一個逗號 foreach (var array in geoExistArray) { if (array[3].Length > 0) array[3].Remove(array[3].Length - 1, 1); } //獲取des值並更新OraDT UpdateOraDT(_ds.Tables[0], geoExistArray); }
UpdateOraDT代碼:
private DataTable UpdateOraDT(DataTable dt, string[][] geoExistArray) { DataTable ExemDesDT; foreach (var GeoArrary in geoExistArray) { //得出一個須要被訪問的sql db下的全部des,存於ExemDesDT if (GeoArrary[1] == "1") { ExemDesDT = GetExemptionDesSQL(GeoArrary[0], GeoArrary[2]); if (ExemDesDT != null) //遍歷ExemDesDT,若是ExemDesDT中的id_exemption等於OraDt中的desID ,則獲取des foreach (DataRow pyrow in ExemDesDT.Rows) { foreach (DataRow phxrow in dt.Rows) { if (pyrow["id_exemption"] == phxrow["desID"]) phxrow["ExemptionDes"] = pyrow["description"].ToString()); } } } } return dt; }
GetExemptionDesSQL方法:
private DataTable GetExemptionDesSQL(string geo, string desidList) { DataTable ExemDesDT = new DataTable(); string query = " select des from taxDes where desid in (" + desidList+")"; Database DbGEO = DbGEOFactory.CreateDatabase(geo); System.Data.Common.DbCommand sqlCmd = DbPyramid.GetSqlStringCommand(query); ExemDesDT = DbGEO.ExecuteDataSet(sqlCmd).Tables[0]; return ExemDesDT; }