鍍金池/ 教程/ C#/ ASP.NET LINQ
ASP.NET調(diào)試
ASP.NET Web Services
ASP.NET緩存
ASP.NET多線程
ASP.NET面板控件
ASP.NET數(shù)據(jù)綁定
ASP.NET數(shù)據(jù)源
ASP.NET個性化
ASP.Net教程
ASP.NET Ajax控件
ASP.NET生命周期
ASP.NET HTML服務(wù)器
ASP.NET簡介
ASP.NET驗(yàn)證器
ASP.NET多視圖
ASP.NET網(wǎng)站配置
ASP.NET錯誤管理
ASP.NET自定義控件
ASP.NET LINQ
ASP.NET AdRotator控件
ASP.NET客戶端
ASP.NET文件上傳
ASP.NET服務(wù)器控件
ASP.NET開發(fā)環(huán)境配置
ASP.NET管理狀態(tài)
ASP.NET服務(wù)端
ASP.NET數(shù)據(jù)庫訪問(Access)
ASP.NET基本控件
ASP.NET安全
ASP.NET指令
ASP.NET事件處理
ASP.NET第一個程序
ASP.NET日歷控件

ASP.NET LINQ

大多數(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ù)不是直接使用,而是需要進(jìn)行排序,排序,分組,更改等。

因此,如果有一種工具可以使得所有類型的數(shù)據(jù)訪問變得容易,從而允許來自不同數(shù)據(jù)源的數(shù)據(jù)加入并執(zhí)行標(biāo)準(zhǔn)的數(shù)據(jù)處理操作,那么只需幾行代碼就可以獲得很大的幫助。

LINQ 或語言集成查詢就是這樣一個工具。 LINQ 是對.Net Framework 3.5及其管理語言的擴(kuò)展集,它將查詢設(shè)置為對象。并定義了一個通用語法和一個編程模型,用一種通用的語言來查詢不同類型的數(shù)據(jù)。

如:Select,Project,Join,Group,Partition,Set操作等關(guān)系運(yùn)算符在LINQ中實(shí)現(xiàn),而.Net framework 3.5+中的 C# 和VB編譯器支持LINQ語法,可以使用配置的數(shù)據(jù)存儲而不依靠使用ADO.NET。

例如,在Northwind數(shù)據(jù)庫中查詢Customers表,使用C#中的LINQ查詢,代碼將是:

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

其中,

  • from關(guān)鍵字在邏輯上循環(huán)了集合的內(nèi)容。
  • 針對集合中的每個對象評估計算帶有where關(guān)鍵字的表達(dá)式。
  • select語句選擇評估對象添加到正在返回的列表中。
  • var關(guān)鍵字用于變量聲明。由于返回的對象的確切類型是未知的,這表明信息將被動態(tài)推斷。

LINQ查詢可以應(yīng)用于從IEnumerable <T>繼承的任何數(shù)據(jù)承載類,這里T是任何數(shù)據(jù)類型,例如:List <Book>

下面來看看一個例子來理解這個概念。打開Visual Studio 創(chuàng)建一個ASP.NET空網(wǎng)站項(xiàng)目:LinqDemo ,添加一個Web窗體頁面文件:Default.aspx -

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>LinQ示例</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <h4>圖書列表示例</h4>
            <asp:Label ID="lblbooks" runat="server"></asp:Label>
        </div>
    </form>
</body>
</html>

該示例使用以下類:Books.cs -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// Books 的摘要說明
/// </summary>
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 Java 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;
    }
}

使用這個類的網(wǎng)頁有一個簡單的標(biāo)簽控件,顯示書的標(biāo)題。Page_Load事件創(chuàng)建書籍列表并通過使用LINQ查詢返回標(biāo)題:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : 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)頁面執(zhí)行時,標(biāo)簽顯示查詢的結(jié)果:

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

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

它相當(dāng)于下面的SQL查詢:

SELECT Title from Books

LINQ運(yùn)算符

除了迄今使用的操作符外,還有其他幾個操作符,它們實(shí)現(xiàn)了所有的查詢語句。下面來看看一些運(yùn)算符和子句。

Join子句

SQL中的“Join子句” 用于連接兩個數(shù)據(jù)表,并顯示包含兩個表的列的數(shù)據(jù)集。LINQ也有這個能力。要理解這個用法,現(xiàn)在添加另一個名為 Saledetails.cs 的類:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

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事件處理程序中添加代碼,以使用join子句在兩個表上進(jìn)行查詢:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class Sales : System.Web.UI.Page
{
    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é)果頁面如圖所示:

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的那些行:

Orderby和Orderbydescending子句

這些子句允許對查詢結(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};

返回的元組是:

Let子句

let子句允許定義一個變量并為其分配一個從數(shù)據(jù)值計算出的值。例如,要計算上述兩個銷售額中的總銷售額,需要計算:

TotalSale = Price of the Book * Sales

要實(shí)現(xiàn)這一點(diǎn),請在Page_Load事件處理程序中添加以下代碼片段:

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

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