国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - 用擴展方法優化多條件查詢(不定條件查詢)

用擴展方法優化多條件查詢(不定條件查詢)

2019-10-13 14:11asp.net教程網 ASP.NET教程

在我們開發過程中,特別是管理系統的開發,經常會遇到多條件查詢(或者叫不定條件查詢)的案例,就是提供給User輸入的查詢條件有多個不同的查詢欄位,而且,在實際使用中并不能確定User會使用哪些條件來當做搜索條件

在我們開發過程中,特別是管理系統的開發,經常會遇到多條件查詢(或者叫不定條件查詢)的案例,就是提供給User輸入的查詢條件有多個不同的查詢欄位,而且,在實際使用中并不能確定User會使用哪些條件來當做搜索條件。 

下圖就是我們實際項目中一個查詢頁面的截圖, 
用擴展方法優化多條件查詢(不定條件查詢) 
User在實際操作中,有可能會只根據[扣帳編號]查詢,那么,只要在[扣帳編號]欄位輸入號碼,其他欄位留空即可,那么查詢語句就只卡[扣帳編號]這條條件也有可能直接根據日前范圍查詢,只要輸入起始日期即可。當然,在實際開發的時候我們是不能預判User的行為的,因此,正常情況下我們都是用Sql拼接的方法來應對這個問題: 

復制代碼代碼如下:

StringBulider sbSql=new StringBulider(); 
sbSql.Append("select * from V_view1 where 1=1 "); 
/*"注意,這里為了確保拼接Sql語句的語法正確,要加上“1=1”,因為可能后面所有的查詢條件都為空,這個語句 要以 "where 1=1" 結尾。 以前也有在園子里看到文章說加上“1=1”對查詢效率有一定影響,這個沒有深入研究過,對此持保留態度鑒于我們這里只針對一般開發,數據量不是很大,所以對于這個問題暫且不做討論*/ 
if(!string.IsNullorEmpty(varGRNO)) 
sbSql.AppendFormat(" and BOLNR = '{0}' ",varGRNO); 


這樣,就在生成Sql語句之前對User的輸入行為做了判斷:對于某個查詢條件,如果User有輸入,則加入Sql的Where條件中,有個沒有輸入,則不予考慮。 
對于日期范圍的判斷,可以這樣寫: 

復制代碼代碼如下:

StringBulider sbSql=new StringBulider(); 
sbSql.Append("select * from V_view1 where 1=1 "); 
if(!string.IsNullorEmpty(varGRNO)) 
sbSql.AppendFormat(" and BOLNR = '{0}' ",varGRNO); 

if(!string.IsNullorEmpty(vardtFrom)) 

sbSql.AppendFormat(" and CRDate >= '{0}' ",Convert.ToDateTime(vardtFrom)); 
if(!string.IsNullorEmpty(vardtTo)) 

sbSql.AppendFormat(" and CRDate <= '{0}' ",Convert.ToDateTime(vardtTo)); 


下面是我們實際開發中的完整代碼(省略了一些無關的邏輯): 

復制代碼代碼如下:

public DataTable GetGRCollections(string varShipto, string varGRNO, string varGRNOto, string varMaterialNO, string varPL, string varPLto, string varCustomerID, string varCustomerID1, string varCustomerPN, string varDateFrom, string varDateTo, string varChecked,string varSupplierPN) 

try 

#region Code Here................ 

DataTable dtResult = new DataTable(); 

StringBuilder sbSql = new StringBuilder(); 
sbSql.Append(" SELECT * ") 
.Append(" FROM V_QueryGR") 
.Append(" WHERE (GRTime>= '" + varDateFrom + " 'and GRTime<='" + varDateTo + "')"); 
if (!string.IsNullOrEmpty(varShipto)) 

sbSql.Append(" and Plant='"+varShipto+"'"); 


if (!string.IsNullOrEmpty(varGRNO)) 

if (!string.IsNullOrEmpty(varGRNOto)) 
sbSql.Append(" and (GRNO>='" + varGRNO +"' and GRNO<='"+varGRNOto+ "')"); 
else 
sbSql.Append(" and GRNO='" + varGRNO + "'"); 

if (!string.IsNullOrEmpty(varMaterialNO)) 

sbSql.Append(" and MaterialNO='"+varMaterialNO+"'"); 


if (!string.IsNullOrEmpty(varPL)) 

if (!string.IsNullOrEmpty(varPLto)) 
sbSql.Append(" and (PackingNO>='" + varPL + "' and PackingNO<='"+varPLto+"')"); 
else 
sbSql.Append(" and PackingNO='" + varPL + "'"); 

if (!string.IsNullOrEmpty(varCustomerID)) 

sbSql.Append(" and CustomID='" + varCustomerID + "'"); 

if (string.IsNullOrEmpty(varCustomerID)) 

ClsCommon ObjCommon = new ClsCommon(userData); 
sbSql.Append(" and CustomID in (" + ObjCommon.GetVendorPermissionString() + ")"); 

if (!string.IsNullOrEmpty(varCustomerID1)) 

sbSql.Append(" and CustomID2='" + varCustomerID1 + "'"); 

if (!string.IsNullOrEmpty(varCustomerPN)) 

sbSql.Append(" and CustomerPN='" + varCustomerPN + "'"); 

if (!string.IsNullOrEmpty(varDateFrom)) 

if (!string.IsNullOrEmpty(varDateTo)) 
sbSql.Append(" and (GRTime>= '" + varDateFrom + "' and GRTime<='" + varDateTo + "')"); 
else 
sbSql.Append(" and PackingNO='" + varDateFrom + "'"); 

if (varChecked == "Checked") 

sbSql.Append(" and CheckPrice=1 "); 

if (varChecked == "UnChecked") 

sbSql.Append(" and CheckPrice=0"); 

if (!string.IsNullOrEmpty(varSupplierPN)) 

sbSql.Append(" and SuplierPN='" + varSupplierPN + "'"); 


try 

ControlHandleDB(); 
dtResult = ControlSqlAccess.GetDataTable(sbSql.ToString()); 

catch 

throw; 

finally 

ControlSqlAccess.CloseConnection(); 


return dtResult; 

#endregion 

catch (CommonObjectsException ex) 



catch (Exception ex) 




這樣一來,如果參數多一點的話,一個簡單的Get方法就要寫50行以上的代碼,雖然不能以代碼的行數來評定開發效率,但這種方法無疑增加了代碼量, 
也降低的代碼的可讀性和可維護性。 
以前,為了給這種情況找到一種更“優雅”,更簡潔的方法,也有在網上找了一些資料,發現其他人的方法也是大同小異,差不多都是這樣按條件拼接。 
園子里有一位同學(現在忘記是哪位了O(∩_∩)O哈!)提出了一種解決方案就是把判斷的邏輯直接寫到Sql語句或者存儲過程中: 

復制代碼代碼如下:

select * from V_view1 where ((ISNULL(@varGRNO,'')<>'' and BOLNR=@varGRNO ) or (1=1)) 


這個方法雖然一定程度上減少了代碼量,但是把業務邏輯混雜在Sql語句中,個人感覺不是太好的方法,而且大大增加了維護的難度。當然,有興趣的同學可以 
自己去研究。 
既然,以上方法都有弊端,那么有沒有更好一點的解放方案呢?答案是肯定的,上次用EF的時候突然想到.Net中的擴展方法能夠對這個問題進行優化。 
首先,來看一下什么事擴展方法,一下是來做MSDN的解釋: 
擴展方法使您能夠向現有類型“添加”方法,而無需創建新的派生類型、重新編譯或以其他方式修改原始類型。 擴展方法是一種特殊的靜態方法,但可以像擴展類型上的實例方法一樣進行調用。 
我們常用的Linq中引用的 using System.Linq 其實就是一個擴展方法庫,更詳細的內容可以參照MSDN和c# 擴展方法奇思妙用(鶴沖天)。在這里,我只舉一個簡單的例子: 
比如,正常情況下判斷一個字符串是否為空是這樣寫: 

復制代碼代碼如下:

string.IsNullOrEmpty(str); 
如果加上一個我們自己擴展的方法: 
/// <summary> 
/// 檢查字符串是否是空(IsNullOrEmpty) 
/// </summary> 
/// <param name="str"></param> 
/// <returns></returns> 
public static bool IsNullOrEmpty(this string str) 

return string.IsNullOrEmpty(str); 


那么以后判斷字符串是否為空就可以這樣: 

復制代碼代碼如下:

str.IsNullOrEmpty(); 


是不是簡潔、優雅了許多呢? 
好,回到正題,看看如何用擴展方法的特性來優化Sql語句的拼接問題。既然擴展方法允許我們以實例方法的方式來調用靜態方法,那么我們是否可以給Sql語句的字符串實例擴展一個方法來對其操作呢? 
比如這個Sql: 

復制代碼代碼如下:

StringBulider sbSql=new StringBulider(); 
sbSql.Append("select * from V_view1 where 1=1 "); 
if(!string.IsNullorEmpty(varGRNO)) 
sbSql.AppendFormat(" and BOLNR = '{0}' ",varGRNO); 


實際上就是對一個變量進行判斷,然后操作字符串實例。 
那么,我們就加行一個這樣的擴展: 

復制代碼代碼如下:

public static string strEquals(this string strSql, string strValue, string ColName) 

if (!string.IsNullOrEmpty(strValue)) 
return string.Format(strSql + " and {0}='{1}' ", ColName, strValue); 
else 
return strSql; 


看到沒有,在方法內部進行參數的非空判斷,那么,上面的代碼就可以這樣寫: 

復制代碼代碼如下:

String strSql="select * from V_view1 where 1=1" 
strSql=strSql.strEquals(varGRNO,BOLNR) 


是不是少了很多代碼? 
如果有更多的參數,我們可以寫的想Linq一樣優雅: 

復制代碼代碼如下:

String strSql="select * from V_view1 where 1=1" 
.strEquals(varGRNO,BOLNR) 
.strEquals(varPLNO,VBELN) 
.strEquals(varPONO,EBELN) 


對于like語句,進行下面的擴展 

復制代碼代碼如下:

public static string strLike(this string strSql, string strValue, string ColName) 

if (!string.IsNullOrEmpty(strValue)) 
return string.Format(strSql + " and {0} like '%{1}%' ", ColName, strValue); 
else 
return strSql; 


和范圍的擴展: 

復制代碼代碼如下:

public static string strEqualsOrBetween(this string strSql, string strStart, string strEnd, string ColName) 

if (string.IsNullOrEmpty(strStart) && string.IsNullOrEmpty(strEnd)) 
return strSql; 
else if (!string.IsNullOrEmpty(strStart) && !string.IsNullOrEmpty(strEnd)) 

return strSql.strBigger(strStart, ColName).strSmaller(strEnd, ColName); 

else if (string.IsNullOrEmpty(strStart) && !string.IsNullOrEmpty(strEnd)) 
return strSql.strEquals(strEnd, ColName); 
else 
return strSql.strEquals(strStart, ColName); 


這樣一來,上面一大段的代碼就可以寫成這樣: 

復制代碼代碼如下:

public DataTable GetGRCollections(string varShipto, string varGRNO, string varGRNOto, string varMaterialNO, string varPL, string varPLto, string varCustomerID, string varCustomerID1, string varCustomerPN, string varDateFrom, string varDateTo, string varChecked,string varSupplierPN) 

try 

#region Code Here................ 

DataTable dtResult = new DataTable(); 

String strSql="select * from V_QueryGR where 1=1" 
.DtEqualsOrBetween(varDateFrom,varDateTo,GRTime) 
.strEquals(varShipto,Plant) 
.strEqualsOrBetween(varGRNO,GRNO) 
.strEquals(varMaterialNO,MaterialNO) 
.strEqualsOrBetween(varPL,PackingNO) 
.strEquals(varCustomerID,CustomID) 
.strEquals(varCustomerID1,CustomID2) 
.strEquals(varCustomerPN,CustomerPN) 
.DtEqualsOrBetween(varDateFrom,varDateTo,GRTime) 
.strEquals(varSupplierPN,SuplierPN) 
try 

ControlHandleDB(); 
dtResult = ControlSqlAccess.GetDataTable(sbSql.ToString()); 

catch 

throw; 

finally 

ControlSqlAccess.CloseConnection(); 


return dtResult; 

#endregion 


catch (CommonObjectsException ex) 



catch (Exception ex) 




對于其他的一下擴展方法,我寫了一個類文件,有興趣的可以點此下載。 
第一次正正經經的寫博文,累死我了。由于自己也是個菜鳥,想把一個問題講清楚讓更多的“菜鳥”也能看懂,難免有些啰嗦,有不足的地方還請大家多多指教。

 

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 欧美电影在线观看 | 欧美日韩精品一区二区三区 | 精品无码三级在线观看视频 | 国产精品毛片久久久久久久av | 91视频com| 亚洲视频在线一区 | 99久久久无码国产精品 | 成年人免费网站 | 精品国产一区三区 | 青青久在线视频 | 精品无码三级在线观看视频 | 欧美日韩精品网站 | 九一视频在线免费观看 | 国产精品久久久久久久福利院 | 欧美视频一二三区 | 国产精品69毛片高清亚洲 | 亚洲天堂中文字幕 | 日韩小视频网站hq | 亚洲精品视频观看 | a视频在线 | 成人午夜精品一区二区三区 | 免费在线黄色网址 | 亚洲精品一区在线观看 | 欧美成人精品一区二区三区 | 在线观看亚洲区 | 日韩在线免费电影 | 精品久久久久久久久久久久久久久久久久久 | 国产一区 | 中文字幕在线导航 | 无毛网站 | 久久精品一区二区三区四区 | 亚洲 精品 综合 精品 自拍 | 中文字幕国产视频 | 精品久久久久久久中文字幕 | 午夜国产在线 | 久久中文字幕在线观看 | 成人精品一区二区三区中文字幕 | 九九热免费精品视频 | 日韩一区二区在线播放 | 欧美久 | 中文久久 |