近來ORM變得越來越普遍,這都歸於一種很具說服力的原因;它可以使開發數據庫驅動的應用程序變得 更快、更省力。但是ORM框架都有點“固執己見”,他們期望開發者遵從特定的規則,當規則被打破的時 候就非常難以使用。最通常的規則之一就是,存儲過程必須總是返回單獨的結果集,其中帶有一致的列的 列表。不幸的是,有很多這樣的存儲過程,其中返回的數據的結果根據它自身內部邏輯的不同而不同。例 如,一個存儲過程可能會接受一個參數,它表示要返回那些列,而另一個參數表示如果它包含了所有行, 那麼就對其進行合計。或者存儲過程的結果可能會根據某些內部的標識而不同,從而應用程序需要檢查輸 出,從而在運行時決定結構。
面對已經確定了的存儲過程集合,而這些存儲過程並非是針對ORM系統所基於的靜態建模的類型所設計 的,大多數.NET開發者會轉而使用DataTable的方法。但是有了.NET 4.0中新創建的對動態類型的支持, 他們會產生另一個主意。如果所有一切——包括存儲過程的名稱、SQL的參數以及得到的對象——都在運 行時處理會怎麼樣呢?
下面是一些由VB和C#編寫的示例代碼。你會注意到VB需要使用Option Strict,而C#大量地使用了它的 新關鍵字“dynamic”。
VB
Using con As New SqlClient.SqlConnection(connectionString)
Dim customer = con.CallSingleProc.CustomerSelect(AccountKey:=12345)
Console.WriteLine(customer.FirstName & " " & customer.LastName)
Dim orders As IList = con.CallListProc.OrderSearch(AccountKey:=12345, MinCreatedDate:=Now.AddDays(-7), MaxCreatedDate:=Now)
Dim totalValue = Aggregate order In orders Into Sum(CDec (order.TotalOrderValue))
Console.WriteLine("This customer ordered a total of $" & totalValue & " last week")
For Each order In orders
Console.WriteLine(vbTab & "Order Key: " & order.OrderKey & " Value: $" & order.TotalOrderValue)
Next
End Using
C#
using (var con = new SqlConnection(connectionString))
{
var customer = con.CallSingleProc().CustomerSelect(AccountKey: 12345);
Console.WriteLine(customer.FirstName + " " + customer.LastName);
IList<dynamic> orders = con.CallListProc().OrderSearch(AccountKey: 12345, MinCreatedDate: DateTime.Now.AddDays(-7), MaxCreatedDate: DateTime.Now);
var totalValue = orders.Sum(order => (decimal) order.TotalOrderValue);
Console.WriteLine("This customer ordered a total of $" + totalValue + " last week");
foreach (var order in orders)
{
Console.WriteLine("\tOrder Key: " + order.OrderKey + " Value: $" + order.TotalOrderValue);
}
}