該系列教程描述了如何采用手動的方式映射你的對象類到數據表(而不是使用象SqlMetal這樣的自動化工具)以便能夠支持數據表之間的M:M關系和使用實體類的數據綁定。即使你選擇使用了自動生成類的工具,理解這一實現過程可以讓你更加方便地對你的應用程序加以擴展。
下面闡述本文的目標以及該示例程序為初級開發人員介紹如何學習LINQ的基本要點:
·使用LINQ to SQL將SQL Server數據庫表映射到與之關聯的對象上。
·執行一些簡單的LINQ查詢來檢索數據。
本文詳細為你闡述了如何在你的應用程序中實現LINQ to SQL。附件的示例程序包括了這里探討的所有代碼,還提供了一個簡單的WPF圖形界面程序來顯示通過數據綁定返回的結果集。
開始部分:LINQ to SQL是一種對象關系隱射工具,該工具允許你在.NET 3.5框架平臺上將SQL Server數據庫映射成對象類。
數據庫:該示例使用SQL Server Express作為數據庫,在該數據庫中包涵了Books, Authors, 和 Categories三張數據表。每本書僅僅屬于某一圖書類別,但是每本書可有多個作者,每個作者可以寫多本書。BookAuthors表用于處理books表和authors表之間的多對多關系。為簡單起見,除了Books.Category列以外,其余列都不允許為空。

這些表可以允許我們針對每個主類型進行關系(1:M,M:1,和M:M)之間的映射。
本文的其余部分將描述如何將應用程序的數據表與它們的對象類關聯起來以及如何使用LINQ來檢索結果集。LINQ將使用這些數據表作為示例來闡述這些概念。
應用程序:使用LINQ to SQL, 創建一個.NET 3.5框架之上的工程并添加對程序集 System.Data.Linq的引用。
1、映射DataContext到數據庫
如果你為數據庫創建了一個強類型的DataContext,則該類只會對外提供一個單一的入口點,使得外界可以方便地的訪問你的數據。該類將負責處理數據庫的連接并定義你需要連接的每張數據庫表。
*注意: 在DataContext類中你可以忽略M:M的表連接(例如:BookAuthor),因為它們僅僅使用they're only used behind the scenes to hook up M:M relationships(在本文的后半部分會進行闡述)。
(1)創建一個使用了 [Database]特性的類來擴展 DataContext
創建一個擴展自DataContext的數據庫類,并為其添加[Database]特性以表明該類被映射到了數據庫。
如果你使用的類名與數據庫的名稱不一樣,那么你可以通過使用特性的Name參數進行設定([Database (Name="BookCatalog")])。如果名稱是相同的,此時你可以忽略該參數。
using System.Data.Linq.Mapping; namespace LINQDemo { [Database] public class BookCatalog : DataContext{} } |
(2)添加一個帶數據庫連接字符串的構造函數
添加一個帶有數據庫連接字符串為參數的構造函數,并調用base()方法以告訴父類如何連接你的數據庫。
該構造函數的數據庫連接字符串以參數的形式讀取,它可以是從一個屬性文件讀取,或者直接硬編碼到函數中,在本文的示例中我們就采用了硬編碼這樣的方式(假設這里的字符串連接到SQL Server Compact數據庫,BookCatalog.sdf,該文件與BookCatalog.mdf位于相同的目錄):
public BookCatalog( ) : base( "Data Source=.\\SQLEXPRESS;" + "AttachDbFilename=|DataDirectory|\\BookCatalog.mdf;" + "Integrated Security=True;User Instance=True" ) { } |
注意,在工程中,Book Catalog示例包括了數據庫,和BookCatalog.sdf文件。對于使用LINQ to SQL來說,這不是必要的,在這里僅僅只是加以說明而已。
(3)申明數據表
最后,你可以為每張數據表創建一個類型為Table的對象類集合。
通常,你可以先創建這些類,下面我們來看看這一創建過程。我們將創建三個類(Author, Book, 和Category)--每個類對應一張數據表。因此,我們將為每個類類型添加一個Table集合并將這些集合命名為一個有意義的名字。注意,為數據庫表名對應的類或集合命名不是必須的。我們將在下一節了解如何為數據表指定名稱。
using System.Data.Linq; using System.Data.Linq.Mapping; namespace LINQDemo { [Database] public class BookCatalog : DataContext { public BookCatalog( ) : base( ... ); public Table Authors; public Table Books; public Table Categories; } } |
2、將實體類映射到數據庫表
為連接到應用程序的每張數據庫表創建類對象。我們將以Book表為例子闡述這一實現過程。
(1)創建帶有[Table]特性的類
創建一個特性為Table的Book類將其映射到對應的數據庫表。
為數據庫表的Name參數指定名稱([Table( Name = "Books" )])。這里我們這樣做是因為表的名稱(Books)和我們的類名(Book)不同。如果它們相同,可以忽略該Name參數的設置。
using System.Data.Linq.Mapping; namespace LINQDemo { [Table( Name = "Books" )] public class Book{} } |
(2)使用[Column( IsPrimaryKey = true )]特性添加一個字段作為表的主鍵。
如果你喜歡,你也可以為為其添加一個Column特性,這也是Book Catalog應用程序所采用的方式。
如果你的主鍵在數據庫中設置成了Identity,那么需要添加一個參數IsDbGenerated = true。
相對于數據庫列名,如果你想為字段或屬性設置成不同的名字,可以使用(Name="")標簽來實現.否則程序會默認以你的字段或屬性名稱作為列名,正如我們這里的Book's主鍵:Id那樣。
[Column( IsPrimaryKey = true, IsDbGenerated = true )] public int Id { get; set; } |
(3)使用[Column]特性為表添加其他非關系列
后面部分我們將會回到關系對象上來。現在,咱們開始了解表對象的非主鍵,外鍵列。Book有兩個這樣的列:Title 和 Price。其數據類型由數據庫的money類型轉換到了.NET的decimal類型,以及由varchars類型轉換到了.NET的string類型。LINQ會自動為你處理這些數據類型之間的轉換。
[Column] public string Title { get; set; } [Column] public decimal Price { get; set; } |
Book Catalog應用程序的Author和Category也進行了這樣的處理,即這三個類對象都對應于自己的數據表:
using System.Data.Linq.Mapping; namespace LINQDemo { [Table( Name = "Books" )] public class Book { [Column( IsPrimaryKey = true, IsDbGenerated = true )] public int Id { get; set; } [Column] public string Title { get; set; } [Column] public decimal Price { get; set; } } [Table (Name="Authors")] public class Author { [Column (IsPrimaryKey = true, IsDbGenerated = true )] public int Id { get; set; } [Column] public string Name { get; set; } } [Table (Name="BookCategories")] public class Category { [Column (IsPrimaryKey = true, IsDbGenerated = true )] public int Id { get; set; } [Column] public string Name { get; set; } } } |