??在實(shí)際編程工程中,常常遇到這樣的情況:DataTable并不是數(shù)據(jù)庫(kù)中的,或者DataTable尚未寫(xiě)到數(shù)據(jù)庫(kù),或者從數(shù)據(jù)庫(kù)中讀出的DataTable已經(jīng)在本地被改動(dòng),又沒(méi)有寫(xiě)回?cái)?shù)據(jù)庫(kù)(可能還要作其他改動(dòng)),在這些情況下,要查詢DataTable中的數(shù)據(jù),強(qiáng)大的SQL語(yǔ)言就派不上用場(chǎng)了。
???
??有些.NET程序員采取在數(shù)據(jù)庫(kù)中建立臨時(shí)表等方法來(lái)解決這類查詢問(wèn)題。而我覺(jué)得這種方法不可行,其實(shí)只要用.NET類庫(kù)中提供的DataView類的強(qiáng)大功能(主要是用它的RowFilter屬性),就能方便地解決這類查詢問(wèn)題。下面就舉一個(gè)具體的例子,來(lái)說(shuō)明如何不用SQL語(yǔ)句,用DataView的RowFilter屬性來(lái)查詢。?
????
??用DataView的RowFilter屬性完全能達(dá)到SQL語(yǔ)句SELECT語(yǔ)句所實(shí)現(xiàn)的功能
???
??RowFilter中的查詢語(yǔ)句與SQL語(yǔ)句中SELECT語(yǔ)句的語(yǔ)法和作用都極為相似,以下是摘自MSDN中關(guān)于RowFilter查詢語(yǔ)句的語(yǔ)法說(shuō)明:
???
??/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
???
??用戶定義的值可以用在將與列值進(jìn)行比較的表達(dá)式內(nèi)。字符串值應(yīng)放在單引號(hào)內(nèi)。日期值應(yīng)放在磅符號(hào) (#) 內(nèi)。對(duì)于數(shù)值,允許使用小數(shù)和科學(xué)記數(shù)法。例如:?
????
??"FirstName = 'John'"??
???
??"Price <= 50.00"????
???
??"Birthdate < #1/31/82#"????
???
??對(duì)于包含枚舉值的列,將值強(qiáng)制轉(zhuǎn)換為整數(shù)數(shù)據(jù)類型。例如:?
???
??"EnumColumn = 5"????
???
??運(yùn)算符????
???
??使用布爾值 AND、OR 和 NOT 運(yùn)算符時(shí)允許串聯(lián)。可以使用括號(hào)來(lái)組合子句和強(qiáng)制優(yōu)先級(jí)。AND 運(yùn)算符優(yōu)先于其他運(yùn)算符。例如:?
???
??(LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John'????
???
??在創(chuàng)建比較表達(dá)式時(shí),允許使用下列運(yùn)算符:?
???
??<?
???
??>???
???
??<=????
???
??>=???
???
??<>?
????
??=?
?????
??IN?
?????
??LIKE?
??????
??在表達(dá)式中還支持下列算術(shù)運(yùn)算符:?
??????
??+(加)?
?????
??-(減)?
??????
??*(乘)?
??????
??/(除)?
??????
??%(模數(shù))?
??????
??字符串運(yùn)算符?
??????
??若要連接字符串,請(qǐng)使用 + 字符。字符串比較是否區(qū)分大小寫(xiě)由 DataSet 類的 CaseSensitive 屬性的值來(lái)確定。但是,可以用 DataTable 類的 CaseSensitive 屬性重寫(xiě)此值。?
?????
??通配符?
??????
??在 LIKE 比較中,* 和 % 兩者可以互換地作為通配符。如果 LIKE 子句中的字符串包含 * 或 %,那么這些字符應(yīng)用中括號(hào)([])對(duì)其進(jìn)行轉(zhuǎn)義。如果子句中有中括號(hào),那么中括號(hào)字符應(yīng)用中括號(hào)對(duì)其進(jìn)行轉(zhuǎn)義(例如 [[] 或 []])。在模式的開(kāi)頭和結(jié)尾,或者在模式的結(jié)尾,或在模式的開(kāi)頭允許使用通配符。例如:?
??????
??"ItemName LIKE '*product*'"?
??????
??"ItemName LIKE '*product'"?
??????
??"ItemName LIKE 'product*'"?
??????
??在字符串的中間不允許使用通配符。例如,不允許 'te*xt'。?
?????
??父/子關(guān)系引用?
??????
??通過(guò)在列名稱前面加 Parent,就可以在表達(dá)式中引用父表。例如,Parent.Price 引用父表的名為 Price 的列。?
?????
??通過(guò)在列名稱前面加一個(gè) Child,就可以在表達(dá)式中引用子表中的列。但是,因?yàn)樽雨P(guān)系可以返回多行,所以必須在聚合函數(shù)中包括對(duì)子列的引用。例如,Sum(Child.Price) 將返回子表中名為 Price 的列的總和。?
??????
??如果某個(gè)表有多個(gè)子表,則語(yǔ)法是:Child(RelationName)。例如,如果某個(gè)表有兩個(gè)子表,它們的名稱分別為 Customers 和 Orders,則 DataRelation 對(duì)象被命名為 Customers2Orders,引用將為:?
??????
??Avg(Child(Customers2Orders).Quantity)?
??????
??聚合?
??????
??支持下列聚合類型:?
??????
??Sum(求和)?
??????
??Avg(平均)?
??????
??Min(最小值)?
??????
??Max(最大值)?
??????
??Count(計(jì)數(shù))?
??????
??StDev(統(tǒng)計(jì)標(biāo)準(zhǔn)偏差)?
??????
??Var(統(tǒng)計(jì)方差)。?
?????
??聚合通常沿著關(guān)系執(zhí)行。通過(guò)使用上面列出的函數(shù)之一和上面“父/子關(guān)系引用”中詳述的子表列,來(lái)創(chuàng)建聚合表達(dá)式。例如:?
?????
??Avg(Child.Price)?
??????
??Avg(Child(Orders2Details).Price)?
??????
??聚合也可以在單個(gè)表上執(zhí)行。例如,若要為名為“Price”的列中的數(shù)字創(chuàng)建匯總,就用:?
??????
??Sum(Price)?
???
??有些.NET程序員采取在數(shù)據(jù)庫(kù)中建立臨時(shí)表等方法來(lái)解決這類查詢問(wèn)題。而我覺(jué)得這種方法不可行,其實(shí)只要用.NET類庫(kù)中提供的DataView類的強(qiáng)大功能(主要是用它的RowFilter屬性),就能方便地解決這類查詢問(wèn)題。下面就舉一個(gè)具體的例子,來(lái)說(shuō)明如何不用SQL語(yǔ)句,用DataView的RowFilter屬性來(lái)查詢。?
????
??用DataView的RowFilter屬性完全能達(dá)到SQL語(yǔ)句SELECT語(yǔ)句所實(shí)現(xiàn)的功能
???
??RowFilter中的查詢語(yǔ)句與SQL語(yǔ)句中SELECT語(yǔ)句的語(yǔ)法和作用都極為相似,以下是摘自MSDN中關(guān)于RowFilter查詢語(yǔ)句的語(yǔ)法說(shuō)明:
???
??/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
???
??用戶定義的值可以用在將與列值進(jìn)行比較的表達(dá)式內(nèi)。字符串值應(yīng)放在單引號(hào)內(nèi)。日期值應(yīng)放在磅符號(hào) (#) 內(nèi)。對(duì)于數(shù)值,允許使用小數(shù)和科學(xué)記數(shù)法。例如:?
????
??"FirstName = 'John'"??
???
??"Price <= 50.00"????
???
??"Birthdate < #1/31/82#"????
???
??對(duì)于包含枚舉值的列,將值強(qiáng)制轉(zhuǎn)換為整數(shù)數(shù)據(jù)類型。例如:?
???
??"EnumColumn = 5"????
???
??運(yùn)算符????
???
??使用布爾值 AND、OR 和 NOT 運(yùn)算符時(shí)允許串聯(lián)。可以使用括號(hào)來(lái)組合子句和強(qiáng)制優(yōu)先級(jí)。AND 運(yùn)算符優(yōu)先于其他運(yùn)算符。例如:?
???
??(LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John'????
???
??在創(chuàng)建比較表達(dá)式時(shí),允許使用下列運(yùn)算符:?
???
??<?
???
??>???
???
??<=????
???
??>=???
???
??<>?
????
??=?
?????
??IN?
?????
??LIKE?
??????
??在表達(dá)式中還支持下列算術(shù)運(yùn)算符:?
??????
??+(加)?
?????
??-(減)?
??????
??*(乘)?
??????
??/(除)?
??????
??%(模數(shù))?
??????
??字符串運(yùn)算符?
??????
??若要連接字符串,請(qǐng)使用 + 字符。字符串比較是否區(qū)分大小寫(xiě)由 DataSet 類的 CaseSensitive 屬性的值來(lái)確定。但是,可以用 DataTable 類的 CaseSensitive 屬性重寫(xiě)此值。?
?????
??通配符?
??????
??在 LIKE 比較中,* 和 % 兩者可以互換地作為通配符。如果 LIKE 子句中的字符串包含 * 或 %,那么這些字符應(yīng)用中括號(hào)([])對(duì)其進(jìn)行轉(zhuǎn)義。如果子句中有中括號(hào),那么中括號(hào)字符應(yīng)用中括號(hào)對(duì)其進(jìn)行轉(zhuǎn)義(例如 [[] 或 []])。在模式的開(kāi)頭和結(jié)尾,或者在模式的結(jié)尾,或在模式的開(kāi)頭允許使用通配符。例如:?
??????
??"ItemName LIKE '*product*'"?
??????
??"ItemName LIKE '*product'"?
??????
??"ItemName LIKE 'product*'"?
??????
??在字符串的中間不允許使用通配符。例如,不允許 'te*xt'。?
?????
??父/子關(guān)系引用?
??????
??通過(guò)在列名稱前面加 Parent,就可以在表達(dá)式中引用父表。例如,Parent.Price 引用父表的名為 Price 的列。?
?????
??通過(guò)在列名稱前面加一個(gè) Child,就可以在表達(dá)式中引用子表中的列。但是,因?yàn)樽雨P(guān)系可以返回多行,所以必須在聚合函數(shù)中包括對(duì)子列的引用。例如,Sum(Child.Price) 將返回子表中名為 Price 的列的總和。?
??????
??如果某個(gè)表有多個(gè)子表,則語(yǔ)法是:Child(RelationName)。例如,如果某個(gè)表有兩個(gè)子表,它們的名稱分別為 Customers 和 Orders,則 DataRelation 對(duì)象被命名為 Customers2Orders,引用將為:?
??????
??Avg(Child(Customers2Orders).Quantity)?
??????
??聚合?
??????
??支持下列聚合類型:?
??????
??Sum(求和)?
??????
??Avg(平均)?
??????
??Min(最小值)?
??????
??Max(最大值)?
??????
??Count(計(jì)數(shù))?
??????
??StDev(統(tǒng)計(jì)標(biāo)準(zhǔn)偏差)?
??????
??Var(統(tǒng)計(jì)方差)。?
?????
??聚合通常沿著關(guān)系執(zhí)行。通過(guò)使用上面列出的函數(shù)之一和上面“父/子關(guān)系引用”中詳述的子表列,來(lái)創(chuàng)建聚合表達(dá)式。例如:?
?????
??Avg(Child.Price)?
??????
??Avg(Child(Orders2Details).Price)?
??????
??聚合也可以在單個(gè)表上執(zhí)行。例如,若要為名為“Price”的列中的數(shù)字創(chuàng)建匯總,就用:?
??????
??Sum(Price)?