<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經轉移至github,大家請訪問 http://qaseven.github.io/

    步步學LINQ to SQL:為實體類添加關系

      本文詳細為你闡述了如何在你的應用程序中實現LINQ to SQL。附件的示例程序包括了這里探討的所有代碼,還提供了一個簡單的WPF圖形界面程序來顯示通過數據綁定返回的結果集。

      本部分描述如何實現表間的映射關系:M:1,1:M和M:M。但是這里不會討論1:1的映射關系,你可以在M:1的關系中發現這種1:1的映射關系。因此,從這里開始,我們將使用Book作為示例為你一步一步講述這一實現過程。

      映射M:1的關系

      Book 對象與Category 對象是多對一的關系(M:1),因為一本書僅能屬于某一個類別(并且每個類別能夠包涵很多本書):

      在數據庫中,Book.catalog字段作為該表的外鍵,而在Category中作為主鍵。然而,在你的對象模型中,你很可能想讓book.Catalog表示一個實際的Catalog對象(不僅僅是ID)。此時,你可以通過創建兩個私有字段來實現這一映射關系,然后再對Category對象暴露一個公有屬性。

      1、添加一個私有字段以進行其他表的關聯

      添加一個私有字段,將其映射到Book.category數據庫表的外鍵列。

      如果允許該字段為NULL,使用一個空類型即可實現(如,采用Int?的方式)。

      我將這個字段命名為categoryId(為了區別于我們后面將要創建的公有屬性Category)。這意味著在Column特性上我必須得設置Name參數,因為我的字段名字和數據庫表的字段名稱不同:

    [Column( Name="Category")]privateint?categoryId;

      2、添加一個引用其他表的私有EntityRef類型字段

      添加一個私有類型的EntityRef字段以實現對Category實例的引用。雖然這會使得公有屬性Category扮演一個后臺字段的角色,但是通過使用EntityRef類型,仍然能達到延遲加載的目的(意思是LINQ不會即時從數據庫獲取數據直到我們真正想要數據的時候)。初始化EntityRef字段實例,以阻止NullReferenceExceptions發生。萬一在某個地方你需要使用該對象的實例(如,Category)而此時又沒有任何實例(Book)可用。

    privateEntityRef _category=newEntityRef( );

      3、使用[Association]特性添加一個公有屬性進行類的關聯

      最后,創建類型為public的Category屬性,該屬性用于接收實際的Category實例。 使用下面的參數為該屬性添加Association特性:

      ● 數據庫兩表之間的是關系名稱Name(在本例為FK_Books_BookCategories))

      ● IsForeignKey = true標記指定該類對應數據表的外鍵(在下面的ThisKey參數中進行了指定)。

      ● 使用剛才創建的字段為該特性設置兩個參數:

      (1)ThisKey用于指定到其它表的外鍵:categoryId。

      (2)Storage指定EntityRef用于接收其他類的實例:_category。

      在屬性內部,代碼的getter/setter訪問器用于使用category的Entity屬性,它包涵實際的Category實例:

    [Association( Name = "FK_Books_BookCategories",
    IsForeignKey = true, Storage = "_category", ThisKey = "categoryId" )]
    public Category Category{
    get { return _category.Entity; }
    set { _category.Entity = value; }
    }

      從M:1的關系上訪問數據

      現在你可以通過這種關系以面向對象的方式訪問Category的數據。例如,book.Category.Name:

    foreach( var book in bookCatalog.Books ) {
    string categoryName = book.Category.Name;
    }



     在關聯表中的M:1關系

      現在,咱們一起看看如何在M:M關聯表中實現M:1的關系。當我們遇到表之間的關系為M:M時,正如這里的BookAuthors,當然,連接表的關系仍然是由兩個M:1關系構成。

      例如,BookAuthor包涵一個到Book的M:1關系和一個到Author的M:1關系來構成M:M的關系:

      不幸的是,你仍然需要創建一個類來映射這個關聯表。然而,由于外鍵的原因,它僅僅用于映射的關系,你可以通過設置類的訪問修飾符為internal來保持僅對外提供一個公共接口。

      1、使用[Table]特性創建一個內部類用于映射需要連接的表

      以BookAuthors類相同的方式創建為其他實體類,但是不要將其標記為public:

    using System.Data.Linq;
    using System.Data.Linq.Mapping;
    namespace LINQDemo
    {
    [Table( Name = "BookAuthors" )]
    class BookAuthor{}
    }

      2、映射兩表之間的M:1關系,指定它們將其作為主鍵

      為Book和Author創建一個M:1的關系并以相同的方式為Book:Catalog創建關系。注意數據庫中BookAuthors表的關系以下面的方式命名:

      ● BookAuthor:Authors關系被命名為 FK_BookAuthors_Authors

      ● BookAuthor:Books 關系被命名為FK_BookAuthors_Books

      分別在它的兩個Column特性上為其添加IsPrimaryKey = true的屬性以指示BookAuthors的主鍵由這兩個值構成:

    [Table( Name = "BookAuthors" )]
    class BookAuthor
    {
    [Column( IsPrimaryKey = true, Name = "Author" )] private int authorId;
    private EntityRef _author = new EntityRef( );
    [Association( Name = "FK_BookAuthors_Authors", IsForeignKey = true,
    Storage = "_author", ThisKey = "authorId" )]
    public Author Author {
    get { return _author.Entity; }
    set { _author.Entity = value; }
    }
    Column( IsPrimaryKey = true, Name = "Book" )] private int bookId;
    private EntityRef _book = new EntityRef( );
    [Association( Name = "FK_BookAuthors_Books", IsForeignKey = true,
    Storage = "_book", ThisKey = "bookId" )]
    public Book Book {
    get { return _book.Entity; }
    set { _book.Entity = value; }
    }
    }

      雖然我們已經探討了M:1的關系,但不幸的是,你仍然還不能使用BookAuthor做一些有趣的事,當我們在下面討論M:M的關系時,將繼續回到表連接的探討話題上來。但首先,通過理解如何映射1:M的關系,我們可以看看Book:Catalog的關系來完整理解M:M的關系。

      映射1:M關系

      添加一個1:M的關系使得你可以獲得一個屬于Category的所有書籍列表。

      1、在其它類中映射外鍵

      即使你正在為Category添加關聯關系,它仍然需要知道如何關聯到Book本身。因此,你僅需要確保你的Book類已經映射到了對應的列,該列應該是關聯到Category的外鍵。如果你這樣實現,那么你已經完成了1:M的關系,因此這時你所要做的就是指定字段名:categoryId:

     

    [Table( Name = "Books" )]
    public class Book
    {
    ...
    [Column( Name = "Category" )] private int? categoryId;

     

      2、映射你自己的主鍵

      LINQ會比較Book的外鍵和Category的外鍵,因此你需要映射Category.Id并標識其作為主鍵([Column (IsPrimaryKey = true)])。再次,如果你繼續這個步驟,你已經在實體類中完成了該過程的創建。因此,所要做的僅僅是為該屬性名Id添加一個注釋:

     

    [Table (Name="BookCategories")]
    public class Category
    {
    [Column ( IsPrimaryKey = true, IsDbGenerated = true )] public int Id { get; set; }
    ...

     

      3、添加一個私有的EntitySet類型以實現對其他表的引用

      添加一個私有的EntitySet字段來接收屬于該Category的書籍。這將讓我們的公有Books屬性扮演字段的角色。類似地,EntityRef,EntitySet會引起對Books的加載延遲直到我們實際訪問它的時候(因此,當我們需要查看一個類別的時候,我們不必每次都返回所有書的列表)。

      初始化EntitySet字段以避免NullReferenceExceptions異常的發生,比如在你沒有設置兩邊關系的時候(如一個類別沒有書籍的時候)

     

    private EntitySet _books = new EntitySet();

     

      4、為相關聯的類添加屬性

      最后創建公有Books屬性,它用于接收在對應類別中的書籍。為該屬性添加一個Association特性。并設置數據庫關系的名稱參數為Name (FK_Books_BookCategories),以及使用剛才創建這個字段的特性所需要的三個參數:

      ● OtherKey指定關聯到其他類(Book)的字段,該字段接收所關聯的外鍵:categoryId

      ● ThisKey指定你的主鍵(OtherKey所應該匹配的字段):Id

      ● Storage指定你的EntitySet類型,該類型用來存儲相關聯的Books集合:_books.

      在屬性內部,代碼getter/setter訪問修飾符使用了 _books,它包涵一個實際Book實例的ICollection集合:

     

    [Association( Name = "FK_Books_BookCategories",
    Storage = "_books", OtherKey = "categoryId", ThisKey = "Id" )]
    public ICollection Books {
    get { return _books; }
    set { _books.Assign( value ); }
    }

     

      從1:M 關系上訪問數據

      現在,你可以通過使用category.Books屬性訪問每個類別中的Books列表:

     

    foreach( var category in bookCatalog.Categories ){
    foreach( Book book in category.Books ){
    string bookTitle = book.Title;
    }
    }



      映射M:M 關系

      最后,添加M:M關系,這可以允許你直接從Book實例中訪問每個目錄下下的所有作者,以及從Author實例中直接訪問某個作者寫的所有書籍。

      通過創建BookAuthor類,說明你已經完成了該任務的大部分工作了。并且,你也在前面部分已經了解到當你需要創建1:M時如何實現這一功能。現在,是該將它們整合起來的時候了。再次,我們將使用Book作為示例進行闡述。

      1、從類到關聯的表上添加一個1:M的關系

      Book到BookAuthor 它存在一個1:M的關系,每本書都可以有多個作者,但是每本書作者僅僅屬于一本書。因此,你必須得從先前已有的部分開始進行如下四個步驟:

      ● bookId. 在BookAuthor類中映射到Book的外鍵。你已經這樣實現了,會調用它的:bookId。

      ● 為Book對象定義主鍵。你也已經這樣實現了,會調用它的:Id。

      ● Add an EntitySet that references the other table: _bookAuthors. 添加一個引用其他表的EntitySet類型。

      ● 添加一個BookAuthors屬性(將其設置為私有的,因為這里僅僅用于幫助獲得作者列表),該屬性添加了Association特性并為其設置前面部分設置的三個參數值。

      添加Book對象代碼的第3和第4步如下:

    [Table( Name = "Books" )]
    public class Book
    {
    ...
    private EntitySet _bookAuthors = new EntitySet( );
    [Association( Name = "FK_BookAuthors_Books",
    Storage = "_bookAuthors", OtherKey = "bookId",
    ThisKey = "Id" )]
    private ICollection BookAuthors {
    get { return _bookAuthors; }
    set { _bookAuthors.Assign( value ); }
    }

      雖然你可以在Author中實現相同的功能(因為每個作者都可以有多本書),但是使用authorId取代bookId:

    [Table( Name = "Authors" )]
    public class Author
    {
    ...
    private EntitySet _bookAuthors = new EntitySet( );
    [Association( Name = "FK_BookAuthors_Authors",
    Storage = "_bookAuthors",
    OtherKey = "authorId", ThisKey = "Id" )]
    private ICollection BookAuthors {
    get { return _bookAuthors; }
    set { _bookAuthors.Assign( value ); }
    }

      2、添加一個公有屬性,通過1:M的關系使用LINQ 來檢索枚舉數據。

      最后,通過創建Authors屬性從該書實例的私有書作者列表中檢索所有作者。例如,如果你有一本LINQ In Action的書,該書就有三個作者:Fabrice Marguerie, Steve Eichert, 和Jim Wooley,那么LINQ In Action Book實例將包涵三個BookAuthors的列表:


    posted on 2011-11-24 16:43 順其自然EVO 閱讀(292) 評論(0)  編輯  收藏 所屬分類: 數據庫

    <2011年11月>
    303112345
    6789101112
    13141516171819
    20212223242526
    27282930123
    45678910

    導航

    統計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲日韩精品无码专区加勒比☆| 特级aaaaaaaaa毛片免费视频| 成人人观看的免费毛片| 男女超爽视频免费播放| 亚洲精品国产成人99久久| 成全影视免费观看大全二| 特级毛片aaaa免费观看| 亚洲毛片免费观看| 亚洲高清视频一视频二视频三| 日韩视频免费在线观看| 亚洲免费综合色在线视频| 国产亚洲无线码一区二区| 成人免费a级毛片| a级毛片免费全部播放| 亚洲国产AV一区二区三区四区 | 亚洲综合伊人久久综合| 中文字幕无码视频手机免费看| 特级av毛片免费观看| 亚洲一区二区三区精品视频| 精品亚洲一区二区三区在线观看| 91成年人免费视频| a级黄色毛片免费播放视频| 亚洲中文字幕乱码AV波多JI| 亚洲大尺度无码专区尤物| 四虎AV永久在线精品免费观看| xxxx日本免费| 中文字幕不卡免费视频| 午夜亚洲WWW湿好爽| 亚洲熟妇av一区二区三区下载| 亚洲伊人成无码综合网 | 曰韩无码AV片免费播放不卡| 亚洲人成影院在线高清| 亚洲国产综合无码一区| 亚洲国产成人久久综合区| 成年女人免费视频播放77777 | 国产伦一区二区三区免费| 91在线视频免费91| 亚洲w码欧洲s码免费| 免费日本一区二区| 一级女性全黄久久生活片免费| 亚洲日韩一区二区三区|