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

走進 LINQ:LINQ to Objects (下) — 實戰篇

     編輯:關於.NET

理論篇告一段落,進入實戰範例,貫穿後續所有章節。

部落格領域建模

每個用戶擁有一個部落格,每篇文章屬於一個分類,用戶有角色。定義實體:

public class User {
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public string BlogName { get; set; }
    public Role Role { get; set; }
}

public class Role {
    public int RoleId { get; set; }
    public string RoleName { get; set; }
}

public class Post {
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Abstract { get; set; }
    public string Body { get; set; }
    public string UserName { get; set; }
    public int Click { get; set; }
    public int Comments { get; set; }
    public int CategoryId { get; set; }
}

假設啟動時將所有資料載入記憶體:IList<User> users、IList<Post> posts、IList<Role> roles,對這些集合進行 LINQ to Objects 操作。

查詢運算式傳入參數

依 URL 參數 u=yuyijq 查詢該部落主文章,僅需標題與摘要綁定 GridView:

var dataSource = from post in posts
                 where post.UserName == "yuyijq"
                 select post.Title;
mainGridView.DataSource = dataSource;
mainGridView.DataBind();

利用延遲執行特性,可使用變數:

string userName = Request.QueryString["u"];
var dataSource = from post in posts
                 where post.UserName == userName
                 select post.Title;

延遲執行驗證:

string userName = "zhzkl";
var dataSource = from post in posts where post.UserName == userName select post.Title;
userName = "yuyijq";
mainGridView.DataSource = dataSource;
mainGridView.DataBind(); // 實際繫結 yuyijq 的文章

非泛型集合查詢

舊版 ArrayList 實作 IEnumerable,需轉型:

var dataSource = from post in posts.Cast<Post>()
                 where post.UserName == userName
                 select post.Title;

Cast<T>() 逐一轉型,若有無法轉型元素會拋例外。保險用 OfType<T>() 僅保留可轉型元素。

動態排序

使用者可自訂排序依據(點擊率、評論數等)。OrderBy 需傳入 key selector delegate,可封裝排序方法:

public IEnumerable<Post> Sort<TKey>(string userName, Func<Post, TKey> selector, bool isAsc) {
    var newPosts = from post in posts where post.UserName == userName select post;
    return isAsc ? newPosts.OrderBy(selector) : newPosts.OrderByDescending(selector);
}

多重排序:orderby post.Click, post.Comments 會轉為 OrderBy(...).ThenBy(...)。

分組

依 UserName 分組:

var dataSource = from post in posts group post.Title by post.UserName;

多鍵分組需用匿名型別:

var dataSource = from post in posts group post.Title by new { post.UserName, post.CategoryId };

使用 into 繼續查詢:

var dataSource = from post in posts
                 group post by post.UserName into grouping
                 select new { Key = grouping.Key, TotalClick = grouping.Sum(p => p.Click) };

聯結

依 UserId 找 UserName 再找 Post:

var dataSource = from post in posts
                 join user in users on post.UserName equals user.UserName
                 where user.UserId == 2
                 select post;

注意:聯結條件用 equals 而非 ==。

總結

本篇以實例說明重點用法。LINQ 雖效能略遜傳統寫法,但在複雜聯結/分組時程式碼簡潔度極高。效能問題如 Rails 作者所言:「當效能未成問題前,它永遠不是問題」。

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