用ADO.NET管理資料庫

來源:互聯網
上載者:User
ado|資料|資料庫

  使用ADO.NET管理資料庫中的關係(relation)非常簡單。作為返回單個行集合(rowset)到資料存放區(data store)的代替,你可以返回多個行集合并在資料集(DataSet)中將它們關聯起來。在ADO.NET中使用關聯的資料表(DataTable)有很多好處,包括有將資料存放區為階層的能力、更容易更新資料、有在列中使用運算式的能力等等。

  本文介紹ADO.NET中基於列(column-based)的運算式和計算。我將示範資料列(DataColumn)上集合函數的使用、匯總、在整個資料集中執行其它類型的計算以及在資料表之間串連資料列。文中還舉了幾個執行個體。

  在SQL查詢中合計(summing)和平均值(averaging)對你來說很老套了,這要感謝ANSI SQL中有類似SUM 和AVG的集合函數。SQL允許列的計算,例如按次序把產品單價乘以數量產生擴充價格。現在ADO.NET提供了一條途徑擴充這些資料來源之外的特徵並進入n層結構應用程式中間或上層。在ADO.NET中使用列運算式,你能用資料集中的計算值建立自己的列,在同一行中計算其它列的值,甚至通過資料關係(DataRelation)從父資料表或子資料工作表擷取值。使用ADO.NET中的基於列的運算式和計算形成了新的管理資料的技術。

  當然,在ADO.NET中使用基於運算式的列、集合和計算有利也有弊。運算式可用於資料集的單個資料表或者通過資料關係交叉的兩個資料表對象。本文將解釋在ADO.NET和SQL中基於運算式的列有什麼不同,以及你能從它們中得到什麼東西。本文討論了許多操作,包括用運算式上滾(roll up)和下滾(roll down),它依賴於DataRelation對象的關係。我將示範怎樣在資料列對象中建立運算式,怎樣使用資料集和SQL建立集合函數,怎樣在資料集中上滾和下滾欄位,怎樣在資料集中執行列的計算。

  SQL中的運算式

  SQL運算式為達到不同的目的有多種格式,包括字串格式、使用者定義函數和數學計算。如果SQL語句將姓和名串連到一起、按訂單條目次序計算擴充價格、或者在SQL Server 2000中包含一個使用者定義函數來檢索一個訂單日期,SQL語句就包含了運算式。

  運算式為程式開發人員從資料庫中的其它欄位衍生出的行集合中的傳回值提供了很大的靈活性。關係型和標準的資料庫不會儲存訂單條目的擴充價格,它只儲存單價和數量。擴充價格能從這些值中計算出來,這樣避免了資料不同步。例如,如果在一行中儲存了數量、單價和擴充價格,可能出現數量為100,單價為7,擴充價格為100的情況。這種情況不該發生,但是如果儲存了冗餘資料就可能發生了。事務性資料庫的通用準則是不儲存可以衍生出的資訊,例如擴充價格。

  這樣就有了SQL運算式表演的舞台了。擴充價格能通過在SQL語句中建立計算資料行,將單價乘以數量衍生出。擴充價格又能計算帳戶的折扣率等資訊。下面的SQL代碼示範了怎樣在SQL運算式中連接字串。例子將姓與名串連在一起並返回大寫的全名,名字位於前面:

USE pubs
GO
SELECT au_fname AS FirstName,
au_lname AS LastName,
au_lname + ', ' + au_fname AS FullName1,
(UPPER(au_fname) + ' ' + UPPER(au_lname)) AS FullName2
FROM authors
ORDER BY
au_lname,
au_fname

  SQL運算式能夠在行集合中格式化字串並執行計算,但是為了達到這個目的,你要注意一些問題:如果用上面的SQL語句填充資料集,並且首行的數量列被修改了,運算式列不會跟著改變。例如,如果數量為10,價格為7,現在數量變為5,ExtendedPrice列的值仍為70(10×7),資料沒有同步。出現這種情況的主要原因是運算式沒有從SQL語句傳遞到ADO.NET資料集。

  資料列運算式

  運算式也可以通過ADO.NET資料列對象定義。作為通過SQL語句計算擴充價格的替代者,資料列可以被定義用於表現擴充價格。在SQL語句和資料列中使用運算式的區別是,如果運算式中的某個欄位被修改了,資料列會自動更新運算式所定義的欄位,但SQL運算式不會更新資料列。

  下面的代碼示範了怎樣使用SQL語句填充資料集的資料表並建立一個新資料列描述計算運算式,該運算式使用資料集的唯一資料表中的其它欄位得到。接著該資料表的預設視圖被綁定到ASP.NET的一個叫做grdOrderDetail 的DataGrid控制項。

  這段代碼使用訂單詳細資料建立和填充了一個資料集。接著一個列被添加到該資料集的資料表,用於表現該運算式。該列叫ExtendedPrice,資料類型為浮點型,它的運算式是產品單價和數量列。該運算式能涉及資料表的任意資料列,從當前的資料行中取得值。例如,如果第一行數量為10,單價為7,擴充價格列將使用的值為70。

  在計算中運算式可以包括從資料表中其它欄位得到的字面值。例如,定義擴充價格的運算式可以稍作改變,使它考慮折扣率:

oDs.Tables["OrderDetail"].Columns.Add("ExtendedPrice",
typeof(decimal), "(UnitPrice * Quantity) * (1 - Discount)");

  試著改變UnitPrice、Discount或Quantity資料列的值,結果是與從SQL運算式衍生的列不同,ExtendedPrice資料列也被更新了。該特徵對應用程式很重要,特別是在使用者能修改購物車,確認改變,然後查看更新後的總價格的情況下。

  運算式也可以用於表現其它資料類型,例如邏輯型和字元型值。下面的代碼示範了添加一個欄位用於顯示一個作者是否有折扣:

oDs.Tables["OrderDetail"].Columns.Add("GetsDiscount", typeof(bool),
"Discount > 0");

  你能使用AND、OR或NOT條件建立混合運算式來考慮多個條件,這樣可以加強前面的運算式。還有一些操作符,包括LIKE和IN也可以在運算式中使用。

  運算式也能表現字串值,例如從資料表中取得姓和名並串連到一起。下面的程式碼片段將ProductName與ProductID串連在一起:

oDs.Tables["OrderDetail"].Columns.Add("stringfield", typeof(string),
"ProductID + '-' + ProductName");

  函數

  如果你希望列包含有更複雜邏輯的運算式,可以在列中嵌入一些函數。運算式能包含Len、Iif、 IsNull、Convert、Trim和Substring等函數。這些函數為建立運算式提供了更大的靈活性。LenFunction Compute字串的長度:

oDs.Tables["OrderDetail"].Columns.Add("LengthOfProductName",
typeof(int), "Len(ProductName)");

  Iif函數是一個迭代的If語句,象Visual Basic .NET中的IIf一樣。它有三個參數並計算第一個參數的真假。如果第一個參數計算值為真,將從Iif函數返回第二個參數,否則返回第三個參數。下面基本上是一個濃縮的If...Then...Else語句,能簡單地寫成嵌入運算式:

oDs.Tables["OrderDetail"].Columns.Add("Inventory", typeof(string),
"Iif(Quantity < 10,'A few left', 'Plenty in stock')");

  IsNullFunction Compute第一個參數,看它是否與System.DbNull相等。如果計算結果為假,函數返回第一個參數值,如果為真則返回第二個參數值。這在不允許空值,並且希望用Null 字元串或預留位置代替時使用:

oDs.Tables["OrderDetail"].Columns.Add("DiscountString",
typeof(string), "IsNull(Discount, '[null value]')");

  Trim函數刪除字串值尾部的空格。Convert函數將運算式中的資料類型轉換為函數第二個參數所指的資料類型。Substring函數返回字串的一部分,可用於將長字串剪短,只顯示定長的字串,它可以返回字串的任意部分並根據需要與其它的函數組合使用:

oDs.Tables["OrderDetail"].Columns.Add("ShortProduct",
typeof(string), "Substring(ProductName, 1, 10)");

  集合和關係

  運算式中的嵌入集合函數能協助你建立一個表現更複雜邏輯的運算式。如果要建立一個列計算跨多個行的值怎麼辦?最好加入集合函數。

  假定在一個資料集中有類似SQL Server的Northwind資料庫中的訂單到訂單細節的關係結構,那麼用包含集合函數的運算式建立列就很直接。下面的代碼示範了怎樣建立一個包含結構的資料集,在該資料集中訂單位於父資料表而訂單細節位於子資料工作表。這些資料表對象通過一個叫Orders2OrderDetails的資料關係彼此關聯。

  請注意代碼是怎樣建立運算式列並添加到Order 資料表的。第一個運算式建立一個表現每個訂單的詳細資料匯總的列。特別的是OrderTotal資料列有一個運算式用於匯總OrderDetail資料表的基於運算式的ExtendedPrice資料列。你能發現,可以跨越資料關係使用集合函數並將它用在另一個基於運算式的列上。

  ADO.NET中還有其它的集合函數,包括Sum、Avg、Max、Min、StDev、Var和Count。下面的代碼示範了怎樣使用Avg函數得到訂單詳細數量的平均值。關鍵在於使用父(parent)和子(child)關鍵字通過資料關係串連資料:

oDs.Tables["Order"].Columns.Add("AvgQuantity", typeof(decimal),
Avg(Child(Order2OrderDetail).Quantity)");

  Child函數接受資料關係名來擷取子行集合。該參數是可選的,只有在來源資料表中的子關係多於一個時才需要。因此,如果資料表只有一個子表,文法可以簡化:

oDs.Tables["Order"].Columns.Add("AvgQuantity", typeof(decimal),
Avg(Child.Quantity)");

  向下滾動和計算

  Parent函數與Child函數工作類似,只是它沿關係鏈上行到達父資料表。在ADO.NET代碼中這兩個函數協助建立一個假的GROUP BY函數性。

  這些關鍵字的另一個操作是上滾或下滾從一個資料表到另一個資料表不變的值。經常有人問我怎樣將一個父資料表和子資料工作表串連成一個資料表,這樣才能在一個DataGrid控制項中顯示。使用父關鍵字可以將欄位下滾到子資料工作表,接著只將該子資料工作表綁定到DataGrid控制項。例如,需要顯示OrderDetail資料表中每一行的訂單日期,可以添加一個使用父關鍵字的資料列:

oDs.Tables["OrderDetail"].Columns.Add("OrderDate", typeof(string),
"Parent.OrderDate");

  這個特徵使得不需要作任何計算就可以上滾和下滾欄位。使用Child關鍵字可以從父表中下滾欄位並綁定到DataGrid控制項。執行該操作後你得到了一個兩位小數的行集合,與從SQL語句中得到的一樣。要記住,如果打算使用單個行集合中的資料,最好返回單個行集合到資料表。但是,如果你想在資料集中使用關係結構,Parent關鍵字給了你顯示資料的靈活性。

  另一個值得一看的特徵是資料表的Compute函數,該函數使用給定了過慮條件的當前資料表上的集合函數來計算。例如,能給資料表加一列用於計算訂單總價大於999的訂單總數量。

  在下例所示的Compute函數的第一個參數中,執行了一個集合Function Compute合格所有OrderTotal值:

//顯示訂單價格大於999的訂單數量
int iCnt = (int)oDs.Tables["Order"].Compute("Count(OrderTotal)",
"OrderTotal >= 1000");
lblTest.Text = iCnt.ToString() + " orders are at least $1000";

  在第二個參數中指定了過濾器,將集合函數限定為只包含合格行。代碼計算OrderTotal大於或等於1000的行。這是一個在資料表中快速執行計算的強大工具,尤其是能使用過慮。例如,你能很容易地尋找出訂X貨物的顧客數量和訂Y貨物的顧客數量,而不需要迴圈查詢資料庫。

  注意綁定到運算式的資料列對象不能手動更新。綁定到運算式的列不會被覆蓋,除非運算式被刪除。當然,這些資料也不會與資料庫或XML檔案中作為資料來源的列相對應。因此,如果你想將資料儲存到資料庫中時,要記得運算式不能儲存進資料庫。

  上文討論了SQL和ADO.NET中的運算式,示範了運算式所提供的廣泛的函數功能,你能在應用程式中使用它們產生和添加資料。



相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。