一步一步學Linq to sql(二):DataContext與實體


DataContext

 DataContext類型(數據上下文)是System.Data.Linq命名空間下的重要類型,用於把查詢句法翻譯成SQL語句,以及把數據從數據庫返回給調用方和把實體的修改寫入數據庫。

       DataContext提供了以下一些使用的功能:

        以日志形式記錄DataContext生成的SQL

        執行SQL(包括查詢和更新語句)

        創建和刪除數據庫

DataContext是實體和數據庫之間的橋梁,那么首先我們需要定義映射到數據表的實體。

 

定義實體類

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq.Mapping;

namespace DataContext
{
    [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數據庫為例,上述Customers類被映射成一個表,對應數據庫中的 Customers表。然后在類型中定義了三個屬性,對應表中的三個字段。其中,CustomerID字段是主鍵,如果沒有指定Column特性的Name屬性,那么系統會把屬性名作為數據表的字段名,也就是說實體類的屬性名就需要和數據表中的字段名一致。

            ///DataContext
            DataContext ctx = new DataContext(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
            Table<Customer> Customers = ctx.GetTable<Customer>();
            var Cus=from c in Customers
                    where c.CustomerID.StartsWith("A")
                    select new {顧客ID=c.CustomerID, 顧客名=c.Name, 城市=c.City};
            foreach (var ct in Cus.ToList())
            {
                Console.WriteLine("姓名為:{0}在城市{1}",ct.顧客名,ct.城市);
            }

    使用DataContext類型把實體類和數據庫中的數據進行關聯。你可以直接在DataContext的構造方法中定義連接字符串,也可以使用IDbConnection

            IDbConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
            DataContext dc= new DataContext(conn);
            Customers = dc.GetTable<Customer>();

結果顯示如下

 

強類型DataContext

namespace DataContextTest
{
    public partial class NorthWindDataContext: DataContext
    {
 
        public Table<Customer> Customers;
 
        public NorthWindDataContext(IDbConnection connection):base(connection) { }

        public NorthWindDataContext(string connection) : base(connection) { }

    }
}

強類型數據上下文使代碼更簡潔:

            ///強類型DataContext
            NorthWindDataContext NWDC = new NorthWindDataContext(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
            var NWCustomers = from NWs in NWDC.Customers
                              where NWs.CustomerID.StartsWith("A")
                              select new
                                  {
                                      顧客ID = NWs.CustomerID,
                                      顧客姓名 = NWs.Name,
                                      城市 = NWs.City
                                  };
            foreach (var cst in NWCustomers.ToList())
            {
                Console.WriteLine("姓名為:{0}在城市{1}", cst.顧客姓名, cst.城市);
            }

DataContext其實封裝了很多實用的功能,下面一一介紹。

日志功能

            //日志功能
            NorthWindDataContext NWDC = new NorthWindDataContext(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
            StreamWriter sw = new StreamWriter("log.txt", true); // Append
            NWDC.Log = sw;
            var NWCustomers = from NWs in NWDC.Customers
                              where NWs.CustomerID.StartsWith("A")
                              select new
                                  {
                                      顧客ID = NWs.CustomerID,
                                      顧客姓名 = NWs.Name,
                                      城市 = NWs.City
                                  };
            foreach (var cst in NWCustomers.ToList())
            {
                Console.WriteLine("姓名為:{0}在城市{1}", cst.顧客姓名, cst.城市);
            }
            sw.Close();

   運行程序后在目錄生成了log.txt,每次查詢都會把諸如下面的日志追加到文本文件中:

應該說這樣的日志對於調試程序是非常有幫助的。

探究查詢

            ///探究查詢
            NorthWindDataContext ctxc = new NorthWindDataContext(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
            var select = from cc in ctxc.Customers where cc.CustomerID.StartsWith("A") select new { 顧客ID = cc.CustomerID, 顧客名 = cc.Name, 城市 = cc.City };
            DbCommand cmd = ctxc.GetCommand(select);
            Console.WriteLine(cmd.CommandText);
            foreach (DbParameter parm in cmd.Parameters)
                Console.WriteLine(string.Format("參數名:{0},參數值:{1}", parm.ParameterName, parm.Value));
            Customer customer = ctxc.Customers.First();    ///修改第一條記錄
            customer.Name = "aehyok";
            IList<object> queryText = ctxc.GetChangeSet().Updates;
            Console.WriteLine(((Customer)queryText[0]).Name);

  在這里,我們通過DataContextGetCommand方法獲取了查詢對應的DbCommand,並且輸出了CommandText和所有的DbParameter。之后,我們又通過GetChangeSet方法獲取了修改后的實體,並輸出了修改內容。

執行查詢

            ///執行查詢
            NorthWindDataContext ctx = new NorthWindDataContext(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
            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%'");
            foreach (var ct in customers)
            {
                Console.WriteLine("姓名為:{0}在城市{1}", ct.Name, ct.City);
            }

  前一篇文章已經說了,雖然Linq to sql能實現90%以上的TSQL功能。但是不可否認,對於復雜的查詢,使用TSQL能獲得更好的效率。因此,DataContext類型也提供了執行SQL語句的能力。代碼的執行結果如下圖:

創建數據庫

 

    [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) { }
    }
            ///創建數據庫
            Console.WriteLine("創建數據庫");
            testContext ctx = new testContext(ConfigurationManager.ConnectionStrings["ConnStringTest"].ConnectionString);
            ctx.CreateDatabase();

 段代碼在數據庫中創建了名為NorthwindTest的數據庫,因為我在配置文件中創建的如下字符串連接

<add name="ConnStringTest" connectionString="server=.;database=NorthwindTest;uid=sa;pwd=saa"/>

 那么以及test數據庫表也會一同被創建。同時,DataContext還提供了DeleteDatabase()方法,在這里就不列舉了。

 

使用DbDataReader數據源

            ///使用DbDataReader數據源
            var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);

            var ctx = new DataContext(conn);

            var cmd = new SqlCommand("select * from customers where CustomerID like 'A%'", conn);

            conn.Open();

            var reader = cmd.ExecuteReader();
            var Recorders = ctx.Translate<Customer>(reader);
            foreach (var cus in Recorders)
            {
                Console.WriteLine("姓名為{0}城市為{1}",cus.Name,cus.City);
            }
            conn.Close();

 你同樣可以選擇使用DataReader獲取數據,增加了靈活性的同時也增加了性

 

總結

  看到這里,你可能會覺得手工定義和數據庫中表對應的實體類很麻煩,不用擔心,VS提供了自動生成實體類以及關系的工具,工具的使用將在以后講解。今天就講到這里,和DataContext相關的事務、加載選項、並發選項以及關系實體等高級內容也將在以后講解。

示例代碼下載地址http://files.cnblogs.com/aehyok/DataContext.zip


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM