鍍金池/ 教程/ C#/ 語言集成查詢
調(diào)試
管理狀態(tài)
Panel 控件
Web 服務(wù)
語言集成查詢
數(shù)據(jù)源
基礎(chǔ)控件
廣告輪轉(zhuǎn)器
服務(wù)器端
服務(wù)器控件
ADO.NET
多線程
HTML 服務(wù)器
生命周期
Ajax 控制
客戶端
異常處理
環(huán)境設(shè)置
部署
個性化
驗(yàn)證器
多視圖
日歷
文件上傳
ASP.NET - 數(shù)據(jù)綁定
數(shù)據(jù)庫存取
實(shí)例
自定義控件
簡介
配置
數(shù)據(jù)緩存
安全性
指令
事件處理

語言集成查詢

大多數(shù)應(yīng)用都是以數(shù)據(jù)為中心的,然而大多數(shù)的數(shù)據(jù)倉庫是關(guān)系型數(shù)據(jù)庫。這些年,設(shè)計者和開發(fā)者設(shè)計了基于對象模型的應(yīng)用程序。

對象來負(fù)責(zé)連接訪問數(shù)據(jù)的組件——稱為數(shù)據(jù)訪問層( DAL )。這里我們需要考慮三點(diǎn):

  • 一個應(yīng)用程序所需要的所有數(shù)據(jù)可以不存儲在一個資源中。這個資源可以是關(guān)系型數(shù)據(jù)庫、業(yè)務(wù)對象、XML文件或者一個WEB服務(wù)器。
  • 訪問內(nèi)存中的對象要比訪問數(shù)據(jù)庫、XML文件中的數(shù)據(jù)更簡單,更廉價。
  • 被訪問到的數(shù)據(jù)不是直接使用的,而是被轉(zhuǎn)存、排序、分組、修改等。

因此如果存在只是用幾行代碼就能實(shí)現(xiàn)輕易整合各種各樣的數(shù)據(jù)——可以整合來自不同源的數(shù)據(jù),并且能夠執(zhí)行基本的數(shù)據(jù)操作的工具,那將非常有用。

語言集成查詢( LINQ )就是上述那樣的一種工具。 LINQ 是 .NET Framework 3.5 的一個擴(kuò)展集并且它的管理語言使查詢更類似于是一種對象。它定義了一種通用的語法和程序模型,使我們可以使用一種慣用的語法完成查找不同類型的數(shù)據(jù)。

相關(guān)操作像查找、工程、鏈接、分組、分區(qū)、集合操作等可以在 LINQ 中使用,并且在 .NET Framework 3.5 中的 C# 和 VB 編譯器支持 LINQ 的語法,這就使得它可以通過配置數(shù)據(jù)來存儲,而不需要求助于 ADO.NET。

舉個例子,在 Northwind 數(shù)據(jù)庫中查詢 Constomers 這張表,使用 C# 中的 LINQ ,代碼應(yīng)該是這樣:

var data = from c in dataContext.Customers
where c.Country == "Spain"
select c;

其中:

  • from關(guān)鍵字邏輯上依次通過每個集合。
  • 包含關(guān)鍵字where的表達(dá)式會比較集合中的每個對象。
  • select聲明會選擇被比較出的對象加入到列表中并返回。
  • 關(guān)鍵字var用于變量聲明。因?yàn)榉祷貙ο蟮臏?zhǔn)確類型不明確,它表明信息需要被動態(tài)的推測。

LINQ 查詢語句可以應(yīng)用在任何繼承于 IEnumerable 的有數(shù)據(jù)支撐的類,這里 T 可以是任何一個數(shù)據(jù)類型,例如 List< Book >。

讓我們來看一個示例理解一下概念。示例中使用了如下類:Book.cs

public class Books
{
    public string ID {get; set;}
    public string Title { get; set; }
    public decimal Price { get; set; }
    public DateTime DateOfRelease { get; set; }

    public static List<Books> GetBooks()
    {
        List<Books> list = new List<Books>();
        list.Add(new Books { ID = "001", 
            Title = "Programming in C#", 
            Price = 634.76m, 
            DateOfRelease = Convert.ToDateTime("2010-02-05") });

        list.Add(new Books { ID = "002", 
            Title = "Learn Jave in 30 days", 
            Price = 250.76m, 
            DateOfRelease = Convert.ToDateTime("2011-08-15") });

        list.Add(new Books { ID = "003", 
            Title = "Programming in ASP.Net 4.0", 
            Price = 700.00m, 
            DateOfRelease = Convert.ToDateTime("2011-02-05") });

        list.Add(new Books { ID = "004", 
            Title = "VB.Net Made Easy", 
            Price = 500.99m, 
            DateOfRelease = Convert.ToDateTime("2011-12-31") });

        list.Add(new Books { ID = "005", 
            Title = "Programming in C", 
            Price = 314.76m, 
            DateOfRelease = Convert.ToDateTime("2010-02-05") });

        list.Add(new Books { ID = "006", 
            Title = "Programming in C++", 
            Price = 456.76m, 
            DateOfRelease = Convert.ToDateTime("2010-02-05") });

        list.Add(new Books { ID = "007", 
            Title = "Datebase Developement", 
            Price = 1000.76m, 
            DateOfRelease = Convert.ToDateTime("2010-02-05") });

        return list;
    }
}

在 web 網(wǎng)頁中使用這個類要有簡單的標(biāo)簽控制,來顯示書的標(biāo)題。Page_Load 方法創(chuàng)建了一個書的列表并且通過使用 LINQ 查詢返回標(biāo)題:

public partial class simplequery : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        List<Books> books = Books.GetBooks();
        var booktitles = from b in books select b.Title;

        foreach (var title in booktitles)
            lblbooks.Text += String.Format("{0} <br />", title);
    }
}

當(dāng)網(wǎng)頁被運(yùn)行,標(biāo)簽顯示查詢結(jié)果:

http://wiki.jikexueyuan.com/project/asp-net/images/linq_result.jpg" alt="linq_result.jpg" />

上面的 LINQ 表達(dá)式:

var booktitles = 
from b in books 
select b.Title;

等價于下述 SQL 語句:

SELECT Title from Books

LINQ 運(yùn)算符

除了到目前為止使用過的運(yùn)算符之外,還有很多其他運(yùn)算符來執(zhí)行查詢子句。我們來看一些運(yùn)算符和子句。

join 子句

SQL 中的‘join clause’用來連接兩個數(shù)據(jù)表并顯示在兩個數(shù)據(jù)表中都出現(xiàn)的列中的數(shù)據(jù)集合。LINQ 也可以支持這種功能。為了檢測這一點(diǎn),在之前的工程里增加另一個類名為 Saledetails.cs:

public class Salesdetails
{
    public int sales { get; set; }
    public int pages { get; set; }
    public string ID {get; set;}

    public static IEnumerable<Salesdetails> getsalesdetails()
    { 
        Salesdetails[] sd = 
        {
            new Salesdetails { ID = "001", pages=678, sales = 110000},
            new Salesdetails { ID = "002", pages=789, sales = 60000},
            new Salesdetails { ID = "003", pages=456, sales = 40000},
            new Salesdetails { ID = "004", pages=900, sales = 80000},
            new Salesdetails { ID = "005", pages=456, sales = 90000},
            new Salesdetails { ID = "006", pages=870, sales = 50000},
            new Salesdetails { ID = "007", pages=675, sales = 40000},
        };

        return sd.OfType<Salesdetails>();
    }
}

在 Page_Load 函數(shù)中添加代碼來用 join 子句處理在兩張表里完成查詢:

protected void Page_Load(object sender, EventArgs e)
{
    IEnumerable<Books> books = Books.GetBooks();
    IEnumerable<Salesdetails> sales = Salesdetails.getsalesdetails();

    var booktitles = from b in books join s in sales on b.ID equals s.ID
        select new { Name = b.Title, Pages = s.pages };

    foreach (var title in booktitles)
        lblbooks.Text += String.Format("{0} <br />", title);
}

結(jié)果頁顯示如下:

http://wiki.jikexueyuan.com/project/asp-net/images/linq_result2.jpg" alt="linq_result2.jpg" />

where 子句

where 子句允許在查詢中添加篩選條件。例如,如果你想獲得頁數(shù)多于 500 的書目,可以改變 Page_Load 方法中的句柄成下述樣子:

var booktitles = from b in books join s in sales on b.ID equals s.ID
    where s.pages > 500 select new { Name = b.Title, Pages = s.pages };

查詢語句只返回那些頁數(shù)大于 500 的列:

http://wiki.jikexueyuan.com/project/asp-net/images/linq_result3.jpg" alt="linq_result3.jpg" />

正序倒序排序子句

這些子句允許將查詢結(jié)果進(jìn)行排序。為了查詢出標(biāo)題、頁數(shù)和書的價格,并且按照價格排序,在 Page_Load 方法中的句柄里寫如下代碼:

var booktitles = from b in books join s in sales on b.ID equals s.ID
    orderby b.Price select new { Name = b.Title,  Pages = s.pages, Price = b.Price};

返回的元組是:

http://wiki.jikexueyuan.com/project/asp-net/images/linq_result4.jpg" alt="linq_result4.jpg" />

Let 子句

let 子句允許定義一個變量并且將數(shù)據(jù)計算的一個值賦給它。舉個例子,計從上述兩個銷售值中計算總銷售值,你需要這樣計算:

TotalSale = Price of the Book * Sales

為了完成這個算式,加入下面這個代碼片段在 Page_Load 方法的句柄里:

let 子句允許定義一個變量并且將數(shù)據(jù)計算的一個值賦給它。舉個例子,計從上述兩個銷售值中計算總銷售值,你需要這樣計算:

var booktitles = from b in book join s in sales on b.ID equals s.ID
   let totalprofit = (b.Price * s.sales)
   select new { Name = b.Title, TotalSale = totalprofit};

查詢結(jié)果如下圖所示:

http://wiki.jikexueyuan.com/project/asp-net/images/linq_result5.jpg" alt="linq_result5.jpg" />

上一篇:數(shù)據(jù)緩存下一篇:安全性