1. 程式人生 > 其它 >LINQ to SQL(1):基礎入門

LINQ to SQL(1):基礎入門

LINQ to SQL是在SQL SERVER資料庫上設定一個強型別化介面的方式,LINQ to SQL提供的方式是目前我所見到查詢SQL SERVER最簡單也是最有效的方式,他可以使用自定義的型別與資料表甚至儲存過程進行對應,而不像我們使用ADO.NET那樣,把更多的功夫用在資料型別轉換等等的問題上,當程式執行的時候,LINQ to SQL會將我們使用自己的語言定義的模型中的語言繼承查詢轉換為SQL,然後將他在資料庫上執行,然後將返回的結果轉換為我們自定義的類物件,使用過nhibernate或者ibatis.net的朋友,可能就很熟悉這種方式啦,我個人認為,LINQ to SQL在某些地方彌補了這兩種框架的缺陷,而且,如果我們可以在專案中使用ORM設計器來生成我們需要的模型,毫無疑問,那將會是一件非常幸福的事情,簡單的介紹就寫到這裡,如果您還不瞭解LINQ是個什麼東西,就必須先去看看LINQ的基礎啦,當然,在我的這期博文裡,不會用到太多複雜的LINQ語句

注意:本節以及以後的資料庫示例,我想會放到文章最後,有興趣的朋友可以直接下載,如果您有sql 2000/2005的示例資料庫,就不需要啦 找到northwind(下載),附加到您的資料庫就可以啦。我的環境是.net framework ,開發工具visual studio 2008 SP1 開發語言c#

建立一個控制檯應用程式,在預設情況下,可能沒有對System.Data.Linq的引用,所以,你懂得……

建立一個類,這裡我們叫他Customers.cs,我們使用這個類來對映資料庫中的Customers表,我們首先在類的頂部新增如下指令

using System.Data.Linq;
using System.Data.Linq.Mapping;

然後,我們只需要新增TableAttribute屬性就可以實現對映關係啦,在類的內部,定義屬性,使用ColumnAttribute標記屬性在類中指定與資料中中的類的對映

[Table(Name="Customers")]
    public class Customers
    {
        private string _CustomerID;
        [Column(IsPrimaryKey=true,Storage="_CustomerID")]//IsPrimaryKey指定主鍵,Storage指定儲存區域
        public string CustomerID
        {
            get { return this._CustomerID; }
            set { this._CustomerID = value; }
        }

        private string _City;
        [Column(Storage="_City")]
        public string City
        {
            get { return this._City; }
            set { this._City = value; }
        }
    }

好了,我們已經建立了一個類與一個Customers表進行對映,接來下就是LINQ to SQL中最最最重要的一個類出場啦DataContext,它是用於從資料庫檢索物件和提交更改的主要通道

在專案的Main方法中鍵入如下程式碼

DataContext dc = new DataContext("Data Source=XIAOYAOJIAN;Initial Catalog=Northwind;Integrated Security=True");

            Table<Customers> customers = dc.GetTable<Customers>();
            dc.Log = Console.Out;
            IQueryable<Customers> query = from c in customers
                                          where c.City == "London"
                                          select c;
            foreach (Customers c in query)
            {
                Console.WriteLine(c.CustomerID+" | "+c.City);
            }

這裡需要注意的幾點:

1.在構造DataContext例項物件的時候,傳入的是一個連線字串,當然,它還有好幾種過載

2.真正的查詢是在foreach的時候才真正開始的,在定義linq規則的時候,並沒有查詢

執行這段程式碼,得出的結果基本如下圖所示

下面寫一個有外來鍵關係的兩個表的連結查詢

在Customers.cs中新增如下內容

[Table(Name = "Orders")]
    public class Order
    {
        private int _OrderID = 0;
        private string _CustomerID;
        private EntityRef<Customers> _Customer;
        public Order() { this._Customer = new EntityRef<Customers>(); }

        [Column(Storage = "_OrderID", DbType = "Int NOT NULL IDENTITY",
        IsPrimaryKey = true, IsDbGenerated = true)]
        public int OrderID
        {
            get { return this._OrderID; }
        }

        [Column(Storage = "_CustomerID", DbType = "NChar(5)")]
        public string CustomerID
        {
            get { return this._CustomerID; }
            set { this._CustomerID = value; }
        }

        [Association(Storage = "_Customer", ThisKey = "CustomerID")]
        public Customers Customer
        {
            get { return this._Customer.Entity; }
            set { this._Customer.Entity = value; }
        }
    }

修改上面我們定義的Customers類

[Table(Name="Customers")]
    public class Customers
    {
        private string _CustomerID;
        [Column(IsPrimaryKey=true,Storage="_CustomerID")]
        public string CustomerID
        {
            get { return this._CustomerID; }
            set { this._CustomerID = value; }
        }

        private string _City;
        [Column(Storage="_City")]
        public string City
        {
            get { return this._City; }
            set { this._City = value; }
        }

        private EntitySet<Order> _Orders;
        public Customers()
        {
            this._Orders = new EntitySet<Order>();
        }
        [Association(Storage="_Orders",OtherKey="CustomerID")]
        public EntitySet<Order> Orders
        {
            get { return this._Orders; }
            set { this._Orders = value; }
        }
    }

可以看到這裡我們使用的是EntitySet和EntityRef來做主外來鍵的關聯的

修改Main方法中的程式碼

 DataContext dc = new DataContext("Data Source=XIAOYAOJIAN;Initial Catalog=Northwind;Integrated Security=True");

            var customers = dc.GetTable<Customers>();
            dc.Log = Console.Out;
            var query = from c in customers
                                          where c.Orders.Any()//只要有一個值
                                          select c;
            foreach (Customers c in query)
            {
                Console.WriteLine(c.CustomerID+" | "+c.Orders.Count);
            }

這樣的程式碼,還並不是我們想要的,因為如果我們使用ORM來生成LINQ to SQL模型的話,是沒有像GetTable這種東西出現的,二十在查詢的時候,可以直接使用強型別話的類物件,那麼他是如何實現的呢,繼續往下看

在Customer.cs中名稱空間下新增如下程式碼

 public class Northwind : DataContext
    {
        public Table<Customers> Customers;
        public Table<Order> Orders;
        public Northwind(string connection) : base(connection) { }
    }

這裡,我們實現了一個強型別化的DataContext類,繼承自DataContext類

修改Main方法中的程式碼

Northwind dc = new Northwind("Data Source=XIAOYAOJIAN;Initial Catalog=Northwind;Integrated Security=True");
 var customer = from c in dc.Customers
                           where c.Orders.Any()
                           select c;

            dc.Log = Console.Out;
            foreach (Customers c in customer)
            {
                Console.WriteLine(c.CustomerID + " | " + c.City);
            }

            Console.ReadKey();

這裡我們使用了匿名型別var,在這裡,其實它是一個實現了IQueryable介面的一個物件

這裡我們已經不需要gettable這種方式啦,這樣,我們就實現了一個簡單的使用ORM設計器實現的LINQ to SQL模型,怎麼樣,LINQ to SQL的查詢方式,是不是很讓人心潮澎湃啊