首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

走進 LINQ:LINQ to SQL How Do I (2) — 實體關聯與查詢

     編輯:關於.NET

物件關聯對應中,資料表間必然存在關聯。LINQ to SQL 支援兩種聯結方式:

  1. 使用 where 子句進行查找
  2. 使用 join 子句

基本聯結範例

以 Blog 與 Post 為例,查詢特定文章及其所屬部落格。先定義 Blog 對應:

[Table(Name="blogs")]
public class Blog {
    [Column(Name="blogid", IsPrimaryKey=true, IsDbGenerated=true)] public int Id { get; set; }
    [Column] public int UserId { get; set; }
    [Column] public string Name { get; set; }
    [Column] public DateTime CreateDate { get; set; }
    public IList<Post> Posts { get; set; } // 暫不建立對應
}

Where 子句聯結(不推薦)

var result = from blog in blogs
             from post in posts
             where post.BlogId == blog.Id && post.Id == 2
             select new { BlogName = blog.Name, PostTitle = post.Title, PostBody = post.Body };

產生 SQL 使用舊式 ANSI-82 聯結語法。

Join 子句聯結(推薦)

var result = from blog in blogs
             join post in posts on blog.Id equals post.BlogId
             where post.Id == 2
             select new { BlogName = blog.Name, PostTitle = post.Title, PostBody = post.Body };

產生標準 INNER JOIN SQL。注意:LINQ to SQL 的 on 子句左右順序必須與查詢來源順序對應(outer key selector / inner key selector),否則編譯錯誤。

Outer Join 實作

使用 DefaultIfEmpty() 擴充方法:

var result = from post in posts
             join blog in blogs on post.BlogId equals blog.Id into joinblogs
             from joinblog in joinblogs.DefaultIfEmpty()
             where post.Id == 2
             select new { BlogName = joinblog.Name, PostTitle = post.Title, PostBody = post.Body };

產生 LEFT OUTER JOIN SQL。

物件導向關聯導航(自動聯結)

一般 ORM 框架透過物件關聯自動導航,LINQ to SQL 同樣支援。修改 Blog 對應:

[Association(OtherKey="BlogId")]
public EntitySet<Post> Posts { get; set; }

注意:需使用 EntitySet<T> 取代 IList<T>。查詢 Blog 時,關聯的 Post 自動載入:

var result = from blog in dbContext.GetTable<Blog>()
             where blog.Id == 1
             select blog;
foreach (var blog in result) {
    Console.WriteLine(blog.Name);
    foreach (var post in blog.Posts) Console.WriteLine(post.Title);
}

反向關聯:Post 關聯 Blog

在 Post 類別中加入:

private EntityRef<Blog> _blog;
[Association(Storage="_blog", ThisKey="BlogId")]
public Blog Blog {
    get { return _blog.Entity; }
    set { _blog.Entity = value; }
}

使用 EntityRef<T> 支援延遲載入。查詢 Post 時自動載入所屬 Blog。

多對多關聯

LINQ to SQL 預設不直接支援多對多,但社群有通用解決方案:MSDN 部落格範例。

一對一關聯

雙邊皆使用 EntitySet 並設定 IsUnique=true。範例:User 與 Blog 一對一。

[Association(ThisKey="BlogId", OtherKey="Id", IsUnique=true)]
public EntitySet<Blog> Blog { get; set; }

Blog 端對應:

[Association(ThisKey="UserId", OtherKey="Id", IsUnique=true)]
public EntitySet<User> User { get; set; }

後記

讀者反應篇幅過長,本篇專注關聯主題。系列目標將 LINQ 由淺入深完整講解,每篇為系列一個元組。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved