一步一步学linq to sql(二)
DataContext與實體
?????? DataContext類型(數(shù)據(jù)上下文)是System.Data.Linq命名空間下的重要類型,用于把查詢句法翻譯成SQL語句,以及把數(shù)據(jù)從數(shù)據(jù)庫返回給調(diào)用方和把實體的修改寫入數(shù)據(jù)庫。
?????? DataContext提供了以下一些使用的功能:
l???????? 以日志形式記錄DataContext生成的SQL
l???????? 執(zhí)行SQL(包括查詢和更新語句)
l???????? 創(chuàng)建和刪除數(shù)據(jù)庫
DataContext是實體和數(shù)據(jù)庫之間的橋梁,那么首先我們需要定義映射到數(shù)據(jù)表的實體。
定義實體類
| using System.Data.Linq.Mapping; ? [Table(Name = "Customers")] public class Customer { ??? [Column(IsPrimaryKey = true)] ??? public string CustomerID {get; set;} ? ??? [Column(Name = "ContactName")] ??? public string Name { get; set; } ? ??? [Column] ??? public string City {get; set;} } |
?????? 以Northwind數(shù)據(jù)庫為例,上述Customers類被映射成一個表,對應(yīng)數(shù)據(jù)庫中的 Customers表。然后在類型中定義了三個屬性,對應(yīng)表中的三個字段。其中,CustomerID字段是主鍵,如果沒有指定Column特性的Name屬性,那么系統(tǒng)會把屬性名作為數(shù)據(jù)表的字段名,也就是說實體類的屬性名就需要和數(shù)據(jù)表中的字段名一致。
?????? 現(xiàn)在,創(chuàng)建一個ASP.NET頁面,然后在頁面上加入一個GridView控件,使用下面的代碼進行綁定數(shù)據(jù):
| using System.Data.Linq; ? DataContext ctx = new DataContext("server=xxx;database=Northwind;uid=xxx;pwd=xxx"); Table<Customer> Customers = ctx.GetTable<Customer>(); GridView1.DataSource = from c in Customers where c.CustomerID.StartsWith("A") select new {顧客ID=c.CustomerID, 顧客名=c.Name, 城市=c.City}; GridView1.DataBind(); |
?????? 使用DataContext類型把實體類和數(shù)據(jù)庫中的數(shù)據(jù)進行關(guān)聯(lián)。你可以直接在DataContext的構(gòu)造方法中定義連接字符串,也可以使用IDbConnection:
| using System.Data.SqlClient; ? IDbConnection conn = new SqlConnection("server=xxx;database=Northwind;uid=xxx;pwd=xxx"); DataContext ctx = new DataContext(conn); |
?????? 之后,通過GetTable獲取表示底層數(shù)據(jù)表的Table類型,顯然,數(shù)據(jù)庫中的Customers表的實體是Customer類型。隨后的查詢句法,即使你不懂SQL應(yīng)該也能看明白。從Customers表中找出CustomerID以“A”開頭的記錄,并把CustomersID、Name以及City封裝成新的匿名類型進行返回。
?????? 結(jié)果如下圖:
強類型DataContext
| public partial class NorthwindDataContext : DataContext { ??? public Table<Customer> Customers; ??? public NorthwindDataContext(IDbConnection connection) : base(connection) { } ??? public NorthwindDataContext(string connection) : base(connection) { } } |
?????? 強類型數(shù)據(jù)上下文使代碼更簡潔:
| NorthwindDataContext ctx = new NorthwindDataContext("server=xxx;database=Northwind;uid=xxx;pwd=xxx"); GridView1.DataSource = from c in ctx.Customers where c.CustomerID.StartsWith("A") select new { 顧客ID = c.CustomerID, 顧客名 = c.Name, 城市 = c.City }; GridView1.DataBind(); |
?????? DataContext其實封裝了很多實用的功能,下面一一介紹。
日志功能
| using System.IO; ? NorthwindDataContext ctx = new NorthwindDataContext("server=xxx;database=Northwind;uid=xxx;pwd=xxx"); StreamWriter sw = new StreamWriter(Server.MapPath("log.txt"), true); // Append ctx.Log = sw; GridView1.DataSource = from c in ctx.Customers where c.CustomerID.StartsWith("A") select new { 顧客ID = c.CustomerID, 顧客名 = c.Name, 城市 = c.City }; GridView1.DataBind(); sw.Close(); |
?????? 運行程序后在網(wǎng)站所在目錄生成了log.txt,每次查詢都會把諸如下面的日志追加到文本文件中:
| SELECT [t0].[CustomerID], [t0].[ContactName], [t0].[City] FROM [Customers] AS [t0] WHERE [t0].[CustomerID] LIKE @p0 -- @p0: Input String (Size = 2; Prec = 0; Scale = 0) [A%] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1 |
?????? 應(yīng)該說這樣的日志對于調(diào)試程序是非常有幫助的。
探究查詢
| using System.Data.Common; using System.Collections.Generic; ? NorthwindDataContext ctx = new NorthwindDataContext("server=xxx;database=Northwind;uid=xxx;pwd=xxx"); var select = from c in ctx.Customers where c.CustomerID.StartsWith("A") select new { 顧客ID = c.CustomerID, 顧客名 = c.Name, 城市 = c.City }; DbCommand cmd = ctx.GetCommand(select); Response.Write(cmd.CommandText + "<br/>"); foreach (DbParameter parm in cmd.Parameters) ??? Response.Write(string.Format("參數(shù)名:{0},參數(shù)值:{1}<br/>", parm.ParameterName, parm.Value)); Customer customer = ctx.Customers.First(); customer.Name = "zhuye"; IList<object> queryText = ctx.GetChangeSet().ModifiedEntities; Response.Write(((Customer)queryText[0]).Name); |
?????? 在這里,我們通過DataContext的GetCommand方法獲取了查詢對應(yīng)的DbCommand,并且輸出了CommandText和所有的DbParameter。之后,我們又通過GetChangeSet方法獲取了修改后的實體,并輸出了修改內(nèi)容。
執(zhí)行查詢
| NorthwindDataContext ctx = new NorthwindDataContext("server=xxx;database=Northwind;uid=xxx;pwd=xxx"); string newcity = "Shanghai"; ctx.ExecuteCommand("update Customers set City={0} where CustomerID like 'A%'", newcity); IEnumerable<Customer> customers = ctx.ExecuteQuery<Customer>("select * from Customers where CustomerID like 'A%'"); GridView1.DataSource = customers; GridView1.DataBind(); |
?????? 前一篇文章已經(jīng)說了,雖然Linq to sql能實現(xiàn)90%以上的TSQL功能。但是不可否認,對于復雜的查詢,使用TSQL能獲得更好的效率。因此,DataContext類型也提供了執(zhí)行SQL語句的能力。代碼的執(zhí)行結(jié)果如下圖:
創(chuàng)建數(shù)據(jù)庫
| testContext ctx = new testContext("server=xxx;database=testdb;uid=xxx;pwd=xxx"); ctx.CreateDatabase(); ? [Table(Name = "test")] public class test { ??? [Column(IsPrimaryKey = true, IsDbGenerated = true)] ??? public int ID { get; set; } ? ??? [Column(DbType="varchar(20)")] ??? public string Name { get; set; } } ? public partial class testContext : DataContext { ??? public Table<test> test; ??? public testContext(string connection) : base(connection) { } } |
?????? 這段代碼在數(shù)據(jù)庫中創(chuàng)建了名為testdb的數(shù)據(jù)庫,等同于下面的腳本:
| CREATE TABLE [dbo].[test]( ??? [ID] [int] IDENTITY(1,1) NOT NULL, ??? [Name] [varchar](20) COLLATE Chinese_PRC_CI_AS NULL, ?CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED ( ??? [ID] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] |
?????? 同時,DataContext還提供了DeleteDatabase()方法,在這里就不列舉了。
使用DbDataReader數(shù)據(jù)源
| using System.Data.SqlClient; ? var conn = new SqlConnection("server=xxx;database=Northwind;uid=xxx;pwd=xxx"); var ctx = new DataContext(conn); var cmd = new SqlCommand("select * from customers where CustomerID like 'A%'", conn); conn.Open(); var reader = cmd.ExecuteReader();??????? GridView1.DataSource = ctx.Translate<Customer>(reader); GridView1.DataBind(); conn.Close(); |
?????? 你同樣可以選擇使用DataReader獲取數(shù)據(jù),增加了靈活性的同時也增加了性能。
看到這里,你可能會覺得手工定義和數(shù)據(jù)庫中表對應(yīng)的實體類很麻煩,不用擔心,VS2008提供了自動生成實體類以及關(guān)系的工具,工具的使用將在以后講解。今天就講到這里,和DataContext相關(guān)的事務(wù)、加載選項、并發(fā)選項以及關(guān)系實體等高級內(nèi)容也將在以后講解。
轉(zhuǎn)載于:https://www.cnblogs.com/kingdom_0/articles/2043528.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的一步一步学linq to sql(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ethernet
- 下一篇: js程序中美元符号$是什么