roydux,2010年1月25日
ADO.NET Entity Framework 是一個新的資料存取機制,但因為現存已經大多數使用 ADO.NET 存取資料庫,故與 ADO.NET 之間的連結也是很重要的。
ADO.NET 資料物件
知道 ADO.NET,就應該不會不知道赫赫有名的離線資料庫- DataSet 吧,這個物件與其子物件 DataTable 一起,實作出一個可以儲存資料以及簡單資料搜尋的方式,讓開發人員可以在不連接資料庫的狀況下,存取一個資料庫(或資料表)的複本,而這個複本存在於記憶體中,開發人員可利用 DataTable.Select(),DataTable.Compute() 與 DataView 等物件來存取 DataSet 或 DataTable,無形中可以減少資料庫存取與連線的負擔。因此,在各大以 .NET Framework 為主且以資料庫為核心所開發的應用程式,都可以見到 DataTable 和 DataSet 的身影,而 DataTable 也在某個程度上,扮演了管理資料的角色。
在資料庫和 DataSet/DataTable 間構築資料存取橋樑的工具,就是 DataAdapter,它可以在自動管理連線的情況下,將資料填入 DataSet 或 DataTable 中,在應用 DataSet/DataTable 的程式中也會看到 DataAdapter 的身影,當然不是只有這些物件,也有像 DataReader 與 Command 等物件。
DataSet/DataTable 的基本操作回顧
當資料寫到 DataTable 後,我們可以利用 DataTable.Select() 搜尋資料列;利用 DataTable.Compute() 來計算純量值(Scalar Value);以 DataTable.Rows.Add() 來插入資料列;以 DataTable.Rows.Remove() 來移除資料列。DataSet 則是多個 DataTable 的集合,並且允許在 DataTable 之間有關聯性的存在,關聯性由 DataRelation 來決定。
例如,我們可以利用下列的程式碼來取得一個 Customers 和 Orders 資料表的 DataSet:
SqlConnection conn = new SqlConnection(
"initial catalog=Northwind; data source=NB\\SQL2008; integrated security=sspi");
SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Customers", conn);
DataSet ds = new DataSet();
adapter.TableMappings.Add("Customers", "Customers");
adapter.TableMappings.Add("Orders", "Orders");
adapter.Fill(ds, "Customers");
adapter.SelectCommand.CommandText = "SELECT * FROM Orders";
adapter.Fill(ds, "Orders");
然後我可以搜尋屬於特定客戶的訂單資料:
DataRow[] results = ds.Tables["Orders"].Select("CustomerID = 'QUICK'");
foreach (DataRow r in results)
Console.WriteLine("CustomerID ID: {0}, Order ID: {1}",
r["CustomerID"], r["OrderID"]);
或者計算客戶的訂單數:
Console.WriteLine("Customer: {0}, Orders Count: {1}",
"QUICK", ds.Tables["Orders"].Compute("COUNT(OrderID)", "CustomerID = 'QUICK'"));
在資料操作的便利性來看,DataTable 其實是較簡單的,而且簡單的查詢也可以支援,但查詢語法的限制較多。
LINQ to DataSet:更強的資料查詢與檢索
LINQ 除了可以支援一般性 Collection 物件、資料庫與 Entity Framework 之外,也可以應用在 DataSet 與 DataTable 中,稱為 LINQ to DataSet,讓開發人員能夠利用 LINQ 的能力,對 DataSet 做資料檢索與修改,而且語法遵循 LINQ 的標準語法,只有一些小小的不同。
以前面取得 DataSet 的方式為例,我們可以利用 LINQ 來查詢特定客戶的訂單編號:
var query = from o in ds.Tables["Orders"].AsEnumerable()
where o.Field<string>("CustomerID") == "QUICK"
select new {
OrderID = o.Field<int>("OrderID"),
OrderDate = o.Field<DateTime>("OrderDate") };
也可以查詢特定客戶的訂單數:
var query = from o in ds.Tables["Orders"].AsEnumerable()
where o.Field<string>("CustomerID") == "QUICK"
group o by o.Field<string>("CustomerID");
Console.WriteLine(query.First().Count().ToString());
修改資料
LINQ to DataSet 除了可以檢索資料外,也可以修改指定的資料,例如下列這一支程式碼:
DataTable table = new DataTable();
table.Columns.Add("CustomerID", typeof(System.Guid));
table.Columns.Add("CustomerName", typeof(string));
table.Rows.Add(new object[] { Guid.NewGuid(), "AAA" });
table.Rows.Add(new object[] { Guid.NewGuid(), "BBB" });
table.Rows.Add(new object[] { Guid.NewGuid(), "CCC" });
table.Rows.Add(new object[] { Guid.NewGuid(), "DDD" });
var query = from t in table.AsEnumerable()
select t;
foreach (var r in query)
Console.WriteLine("ID: {0}, NAME: {1}",
r.Field<System.Guid>("CustomerID"), r.Field<string>("CustomerName"));
若想要修改最後一列的資料為EEE的話,可以下這樣的語法:
query.Last().SetField("CustomerName", "EEE");
你也可以利用迴圈來處理值的問題,例如:
DataTable table = new DataTable();
table.Columns.Add("CustomerID", typeof(System.Guid));
table.Columns.Add("CustomerName", typeof(string));
table.Columns.Add("Qty", typeof(int));
table.Columns.Add("Price", typeof(int));
table.Columns.Add("Amount", typeof(int));
table.Rows.Add(new object[] { Guid.NewGuid(), "AAA", 5, 200, 0 });
table.Rows.Add(new object[] { Guid.NewGuid(), "BBB", 8, 540, 0 });
table.Rows.Add(new object[] { Guid.NewGuid(), "CCC", 6, 320, 0 });
table.Rows.Add(new object[] { Guid.NewGuid(), "DDD", 3, 290, 0 });
var query = from t in table.AsEnumerable()
select t;
foreach (var r in query)
{
r.SetField<int>("Amount", r.Field<int>("Qty") * r.Field<int>("Price"));
Console.WriteLine("ID: {0}, NAME: {1}, AMOUNT: {2}",
r.Field<System.Guid>("CustomerID"), r.Field<string>("CustomerName"),
r.Field("Amount"));
不過目前的 LINQ 規格,無法插入與刪除 DataRow,開發人員仍然要以原本的方法來設計。
關聯性查詢
DataSet 可以包含許多的 DataTable,在 DataTable 間也可以設定 DataRelation 來做關聯設定,LINQ 可以針對這個關聯設定來查詢資料,例如用關聯性的方式查詢顧客的訂單列表:
var query = from c in ds.Tables["Customers"].AsEnumerable()
join o in ds.Tables["Orders"].AsEnumerable()
on c.Field<string>("CustomerID") equals o.Field<string>("CustomerID")
select new {
CustomerID = c.Field<string>("CustomerID"),
OrderID = o.Field<int>("OrderID")
};
下一步
由於 LINQ to DataSet 較為簡單,故用少量的篇幅來介紹,接下來我們會進入應用程式中,來說明如何在應用程式中整合 ADO.NET Entity Framework 與 LINQ 功能。
Tags: ADO.NET Entity Framework
分类: .NET | 评论:0 | 浏览:
相关文章:
网站目录
最近发表