在開發的過程中爲了方便,很多時候都用datatable作爲離線數據庫使用,但是在篩選的時候,對同一列多次篩選時,結果出現了錯誤。在此記錄一下這個坑,希望知道原因的大佬給出答案。
同時,我這裏也用其他方法跳過這個坑,基本思路就是,先篩除大於等於5的,然後在得到的結果上繼續篩選小於等於15的,更多條件都可以這樣篩選下去(這個坑只是在大於小於,或者大於等於和小於等於上面發現,其他篩選條件:比如包含,開頭,結尾時用到的like都沒這個問題):
用如下數據測試:
篩選目的很簡單,想篩選序號在5-15之間的數據,按照正常的篩選的代碼爲:
sqlStr="(F1_序號>=5) and (F1_序號<=15)";
DataRow[] drs= importData.Select(sqlStr);
得到的結果如下圖所示:
根據上面的結果,可以看到篩選出來的結果已經出錯了。根據上面的錯誤,將代碼修改爲分開分步篩選,得到的結果就正常了,篩選的結果如下:
下面給出錯誤和正確篩選代碼的完整代碼:
錯誤代碼,可以看到sql是完整構建之後在進行篩選,這樣得到的結果是錯誤的(主要看查詢的地方和代碼):
/// <summary>
/// 執行篩選
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void run_Click(object sender, RoutedEventArgs e)
{
string sqlStr = "";
if (valFile.Children.Count > 0)
{
foreach(Label item in valFile.Children)
{
string temStr = "";//構建單個標籤內部的sql字符串
OneFilerP filterObj = (OneFilerP)item.Tag;
string filterTxt = filterObj.FilterTxt.Text;
if (filterTxt != "")
{
string filterStr = filterObj.FilterStr;
filterTxt = filterTxt.Replace(';', ';');//考慮中文分號的情況
string[] fts = filterTxt.Split(';');
foreach (string key in fts)
{
if(filterStr == "精確")
{
if(temStr == "")
temStr = "(" + item.Content + "='" + key + "'";
else
temStr += " or " + item.Content + "='" + key + "'";
}
else if (filterStr == "包含")
{
if (temStr == "")
temStr = "(" + item.Content + " like '%" + key + "%'";
else
temStr += " or " + item.Content + " like '%" + key + "%'";
}
else if (filterStr == "開頭")
{
if (temStr == "")
temStr = "(" + item.Content + " like '" + key + "%'";
else
temStr += " or " + item.Content + " like '" + key + "%'";
}
else if (filterStr == "結尾")
{
if (temStr == "")
temStr = "(" + item.Content + " like '%" + key + "'";
else
temStr += " or " + item.Content + " like '%" + key + "'";
}
else if (filterStr == "不包含")
{
if (temStr == "")
temStr = "(" + item.Content + " not like '%" + key + "%'";
else
temStr += " or "+ item.Content + " not like '%" + key + "%'";
}
else if (filterStr == "大於")
{
if (temStr == "")
temStr = "(" + item.Content + ">" + key;
else
temStr += " or " + item.Content + ">" + key;
}
else if (filterStr == "小於")
{
if (temStr == "")
temStr = "(" + item.Content + "<" + key;
else
temStr += " or " + item.Content + "<" + key;
}
else if (filterStr == "大於等於")
{
if (temStr == "")
temStr = "(" + item.Content + ">=" + key;
else
temStr += " or " + item.Content + ">=" + key;
}
else if (filterStr == "小於等於")
{
if (temStr == "")
temStr = "(" + item.Content + "<=" + key;
else
temStr += " or " + item.Content + "<=" + key;
}
}
temStr += ")";
}
//組合成全sql字符串
if (temStr != "")
{
if (sqlStr == "")
{
sqlStr = temStr;
}
else
{
sqlStr += " and " + temStr;
}
}
}
}
//查詢
DataRow[] drs= importData.Select(sqlStr);
DataTable ResultDt = null;
if (drs.Count() > 0)
{
ResultDt = drs.CopyToDataTable();
}
else if (drs.Count() == 0)
{
ResultDt = new DataTable();
}
//顯示sql代碼
if(importData==null)
SqlStr.Text = "select * from tableName where " + sqlStr;
else
SqlStr.Text = "select * from " + importData.TableName + " where " + sqlStr;
//保存
if (ResultDt != null)
{
//保存結果
_data.AddTable(this.grid.Tag.ToString(), "2", ResultDt);
runstatus.Text = "運行成功!";
}
else
{
ResultDt = new DataTable();
runstatus.Text = "轉換後無數據!";
}
//顯示到界面
string rekey = this.grid.Tag.ToString();
MoveToggleButtons mvtglbtn = work.allBtns[rekey];
Btn_OneFilter_S showResult = (Btn_OneFilter_S)mvtglbtn.ResultUserControl;
showResult.ShowData.ItemsSource = ResultDt.DefaultView;
}
根據修改思路,將篩選分段進行,正確的代碼如下(主要看查詢的位置和代碼):
/// <summary>
/// 執行篩選
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void run_Click(object sender, RoutedEventArgs e)
{
string sqlStr = "";
DataTable ResultDt = importData.Copy(); ;
if (valFile.Children.Count > 0)
{
foreach(Label item in valFile.Children)
{
string temStr = "";//構建單個標籤內部的sql字符串
OneFilerP filterObj = (OneFilerP)item.Tag;
string filterTxt = filterObj.FilterTxt.Text;
if (filterTxt != "")
{
string filterStr = filterObj.FilterStr;
filterTxt = filterTxt.Replace(';', ';');//考慮中文分號的情況
string[] fts = filterTxt.Split(';');
foreach (string key in fts)
{
if(filterStr == "精確")
{
if(temStr == "")
temStr = "(" + item.Content + "='" + key + "'";
else
temStr += " or " + item.Content + "='" + key + "'";
}
else if (filterStr == "包含")
{
if (temStr == "")
temStr = "(" + item.Content + " like '%" + key + "%'";
else
temStr += " or " + item.Content + " like '%" + key + "%'";
}
else if (filterStr == "開頭")
{
if (temStr == "")
temStr = "(" + item.Content + " like '" + key + "%'";
else
temStr += " or " + item.Content + " like '" + key + "%'";
}
else if (filterStr == "結尾")
{
if (temStr == "")
temStr = "(" + item.Content + " like '%" + key + "'";
else
temStr += " or " + item.Content + " like '%" + key + "'";
}
else if (filterStr == "不包含")
{
if (temStr == "")
temStr = "(" + item.Content + " not like '%" + key + "%'";
else
temStr += " or "+ item.Content + " not like '%" + key + "%'";
}
else if (filterStr == "大於")
{
if (temStr == "")
temStr = "(" + item.Content + ">" + key;
else
temStr += " or " + item.Content + ">" + key;
}
else if (filterStr == "小於")
{
if (temStr == "")
temStr = "(" + item.Content + "<" + key;
else
temStr += " or " + item.Content + "<" + key;
}
else if (filterStr == "大於等於")
{
if (temStr == "")
temStr = "(" + item.Content + ">=" + key;
else
temStr += " or " + item.Content + ">=" + key;
}
else if (filterStr == "小於等於")
{
if (temStr == "")
temStr = "(" + item.Content + "<=" + key;
else
temStr += " or " + item.Content + "<=" + key;
}
}
temStr += ")";
}
//組合成全sql字符串
if (temStr != "")
{
//查詢
DataRow[] drs = ResultDt.Select(temStr);
if (drs.Count() > 0)
{
ResultDt = drs.CopyToDataTable();
}
else
{
ResultDt = new DataTable();
break;
}
//組成sql
if (sqlStr == "")
{
sqlStr = temStr;
}
else
{
sqlStr += " and " + temStr;
}
}
}
}
//顯示sql代碼
if(importData==null)
SqlStr.Text = "select * from tableName where " + sqlStr;
else
SqlStr.Text = "select * from " + importData.TableName + " where " + sqlStr;
//保存
if (ResultDt != null)
{
//保存結果
_data.AddTable(this.grid.Tag.ToString(), "2", ResultDt);
runstatus.Text = "運行成功!";
}
else
{
ResultDt = new DataTable();
runstatus.Text = "轉換後無數據!";
}
//顯示到界面
string rekey = this.grid.Tag.ToString();
MoveToggleButtons mvtglbtn = work.allBtns[rekey];
Btn_OneFilter_S showResult = (Btn_OneFilter_S)mvtglbtn.ResultUserControl;
showResult.ShowData.ItemsSource = ResultDt.DefaultView;
}
最好,希望知道原因的大佬不吝賜教,謝謝~!