Transcript 投影片 1

第十六章
LINQ資料查詢技術
16.1 LINQ基本概念
16.3 LINQ to Objects
16.2 LINQ查詢運算式的使用
16.4 LINQ to SQL
備註:可依進度點選小節
第十六章 LINQ 資料查詢技術
16.1 LINQ 基本概念




在 .NET Framework 3.5 新版功能中,最具影響力
莫過於 LINQ:Language Integrated Query語言
整合式查詢。
LINQ 是在 .NET 程式語言中加入查詢資料的能力。
.NET 語言如 VB 或 C# 可用查詢運算式語法來擴充
資料查詢能力。
查詢運算式語法和 SQL 陳述式類似,透過整合開發
環境智慧輸入功能,更能方便撰寫 LINQ查詢運算式
比撰寫單純 SQL 查詢字串更加方便。
2
堅毅誠樸
第十六章 LINQ 資料查詢技術

使用 LINQ 資料查詢技術最大好處是讓程式設計師
能使用一致性的語法來查詢不同的資料來源。

如查詢物件集合、陣列、XML、SQL Server 資料
庫、DataSet…等,讓程式設計師不需要再學習不
同的資料查詢技術以縮短學習曲線。
3
堅毅誠樸
第十六章 LINQ 資料查詢技術
LINQ 依適用對象分成下列幾種技術類型:
1. LINQ to Objects
可查詢實作 IEnumerable或IEnumerable<T> 介面的集合物件,
如陣列、List、集合、檔案物件的查詢、排序…等。
2. LINQ to SQL
可查詢實作 IQueryable<T> 介面的物件,也可直接對 SQL
Server 資料庫做查詢與資料編輯。
3. LINQ to DataSet
可查詢記憶體內的 DataSet 或 DataTable。
4. LINQ to XML
以前要查詢或排序 XML文件必須透過 XPath 或 XQuery,
透過 LINQ to XML 查詢技術可查詢或排序 XML 文件,
且 LINQ to XML 使用方式與 LINQ to Objects、LINQ to SQL
和 LINQ to DataSet 非常類似。
4
堅毅誠樸
第十六章 LINQ 資料查詢技術
16.2 LINQ查詢運算式的使用







LINQ 查詢運算式是以 from 子句啟始來指定範圍
變數以及所要查詢的集合。
這時會將集合內的元素(或陣列)逐一巡覽放到範圍
變數中進行查詢。
可用 orderby 子句排序
使用 where 設定欲查詢條件。
使用 select 子句定義查詢結果的欄位。
最後將查詢結果傳回給等號左邊指定的變數。
無論是查詢或排序陣列中元素、DataSet、DataTable、
XML、集合物件或 SQL Server 資料庫…等資料來源,
LINQ 查詢運算式的基本結構都很類似。
5
堅毅誠樸
第十六章 LINQ 資料查詢技術
var 變數 = from [type] 範圍變數 in 集合
orderby 欄位名稱1 [ascending | descending][, 欄位名稱2 […] ]
where <條件>
select new {[別名1=]欄位名稱 [, [別名2=欄位名稱2 […] ] ]} ;
6
堅毅誠樸
第十六章 LINQ 資料查詢技術

var 關鍵字只能在方法範圍內使用。

使用 var 所宣告的變數是屬於隱含型別的區域變數。

編譯器會自行判斷使用 var 所宣告變數內的資料,來決
定該變數的資料型別。

資料型別定義完後即無法改變,這和 VB 6.0 自由型別
變數是不一樣。
簡例:
 var i=5;

 var name=”Peter”;
 var money = new double {78.5, 69.23, 78.1};
 var n=5;
 n = “Tom” ;
7
堅毅誠樸
第十六章 LINQ 資料查詢技術




使用var宣告隱含型別的區域變數讓編譯器決定變數
的資料型別。
最主要原因是無法知道 LINQ 查詢運算式所查詢的結果
是陣列、物件、集合、DataSet 或 XML 文件
必須將 LINQ 查詢運算式的查詢結果指定給var所宣告
隱含型別的區域變數來決定查詢結果的資料型別。
撰寫 LINQ 查詢運算式基本上包含下列三個步驟:
 定義資料來源
 撰寫LINQ查詢運算式
 執行查詢。
8
堅毅誠樸
第十六章 LINQ 資料查詢技術


建立Salary 薪資陣列共有 Salary[0]~Salary[4]
5 個陣列元素
練習使用 LINQ查 詢運算式對 Salary 陣列做遞增
排序、遞減排序、找出大於 30,000 的薪資、找出
小於等於 30,000 的薪資、計算薪資平均五種狀況
作查詢,並將查詢結果顯示在表單的 richTextBox1
控制項上面。
9
堅毅誠樸
第十六章 LINQ 資料查詢技術
10
堅毅誠樸
第十六章 LINQ 資料查詢技術
問題分析
找出 Salary 薪資陣列中大於 30,000 薪資:

Step1 定義資料來源
因 Salary 薪資陣列要提供給多個事件處理函式一起共用,在事
件
處理函式外建立 Salary 薪資陣列,做為 LINQ 查詢資料來源。
int[] Salary = new int[] { 50000, 80000, 20000, 30000, 45000 };

Step2 撰寫查詢運算式
找出 Salary 薪資陣列中大於 30,000的薪資,做遞增排序,
最後 將查詢結果傳回 result 隱含型別區域變數。

var result = from s in Salary
orderby s descending
where s > 30000
select s;
11
堅毅誠樸
第十六章 LINQ 資料查詢技術

Step3 執行查詢
透過 foreach{…} 敘述將陣列(集合物件)中的元素
列舉出並顯示在 richTextBox1 控制項上。
foreach (var s in result)
{
richTextBox1.Text += s.ToString() + "\n";
}

上述執行後,richTextBox1 上會顯示
「80000, 50000, 45000」。
12
堅毅誠樸
第十六章 LINQ 資料查詢技術

LINQ 提供很多擴充方法,常用擴充方法說明如
下:
13
堅毅誠樸
第十六章 LINQ 資料查詢技術
Step1 設計輸出入介面
14
堅毅誠樸
第十六章 LINQ 資料查詢技術
FileName : Linq1.sln
01 int[] Salary = new int[] { 50000, 80000, 20000, 30000, 45000 };
02 // 表單載入時執行此事件處理函式
03 private void Form1_Load(object sender, EventArgs e)
04 {
05
richTextBox1.Text = "";
06
var result = from s in Salary
select s;
07
int i = 0;
08
foreach (var s in result)
09
{
10
i++;
11
richTextBox1.Text += i.ToString() + ". " + s.ToString() + "\n";
12
13
}
richTextBox1.Text += "平均薪資:" + result.Average().ToString();
14 }
15
堅毅誠樸
第十六章 LINQ 資料查詢技術
15 // 按遞增排序鈕執行此事件處理函式
16 private void btnSortIncrease_Click(object sender, EventArgs e)
17 {
18 richTextBox1.Text = "遞增排序:\n";
19 var result = from s in Salary // 將Salary陣列所有元素遞增排序
orderby s ascending
select s;
20 int i = 0;
21 foreach (var s in result)
// 將s中所有資料逐一顯示在richTextBox1控制項上
22 {
23
i++;
24
richTextBox1.Text += i.ToString() + ". " + s.ToString() + "\n";
25 }
26 }
27 // 按遞減排序鈕執行此事件處理函式
28 private void btnSortDecrease_Click(object sender, EventArgs e)
29 {
30 richTextBox1.Text = "遞減排序:\n";
31 var result = from s in Salary // 將Salary陣列所有元素遞減排序
orderby s descending
select s;
32 int i = 0;
16
堅毅誠樸
第十六章 LINQ 資料查詢技術
33 foreach (var s in result)
34 {
35
i++;
36
richTextBox1.Text += i.ToString() + ". " + s.ToString() + "\n";
37 }
38 }
39 // 按大於30000鈕執行此事件處理函式
40 private void btnGreater30000_Click(object sender, EventArgs e)
41 {
42 richTextBox1.Text = "大於30000薪資:\n";
43 var result = from s in Salary
orderby s descending
where s > 30000
select s;
44 int i = 0;
45 foreach (var s in result)
46 {
47
i++;
48
richTextBox1.Text += i.ToString() + ". " + s.ToString() + "\n";
49 }
50 richTextBox1.Text+="共 " + result.Count().ToString() + " 人";
51 }
52
17
堅毅誠樸
第十六章 LINQ 資料查詢技術
52 // 按小於等於30000鈕執行此事件處理函式
53 private void btnSmaller30000_Click(object sender, EventArgs e)
54 {
55 richTextBox1.Text = "小於等於30000薪資:\n";
56 var result = from s in Salary
orderby s descending
where s <= 30000
select s;
57 int i = 0;
58 foreach (var s in result)
59 {
60
i++;
61
richTextBox1.Text += i.ToString() + ". " + s.ToString() + "\n";
62 }
63 richTextBox1.Text+="共 "+ result.Count().ToString()+"人";
64 }
65 // 按平均薪資鈕執行此事件處理函式
66 private void btnAvg_Click(object sender, EventArgs e)
67 {
68 Form1_Load(sender, e);
69 }
18
堅毅誠樸
第十六章 LINQ 資料查詢技術
16.3 LINQ to Objects


LINQ to Objects 可透過 LINQ 查詢運算式來查詢
實作 IEnumerable 或 IEnumerable <T> 介面集合
的物件。
您可用 LINQ 來查詢任何可列舉集合,如上一範
例的陣列、List<T>、ArrayList<T> 或是使用者定
義的物件集合。
19
堅毅誠樸
第十六章 LINQ 資料查詢技術
先定義 Employee 類別有員工編號、姓名、信箱、雇用日期
薪資、是否已婚 六個屬性。
在表單載入Form1_Load事件處理函式建立emp[0]~emp[4]
五個員工物件記錄後,接著透過員工編號、薪資、雇用
日期來做遞增排序,並將排序的結果顯示在豐富文字方塊
上。也可在文字方塊內輸入要查詢的員工編號並按
鈕來查詢是否有該位員工,執行結果如下圖。
20
堅毅誠樸
第十六章 LINQ 資料查詢技術

下列分別按
遞增排序結果。
、
、
鈕所進行的
21
堅毅誠樸
第十六章 LINQ 資料查詢技術
22
堅毅誠樸
第十六章 LINQ 資料查詢技術

Step1
建立名稱為 Linq2 的 Windows Form 應用程式專案。

Step2 設計Employee.cs 員工類別檔
在Employee類別定義員工編號、姓名、信箱、薪資、
員工編號、是否已婚共有六個屬性:
23
堅毅誠樸
第十六章 LINQ 資料查詢技術
FileName : Employee.cs
01 using System;
02 using System.Collections.Generic;
03 using System.Linq;
04 using System.Text;
05
06 namespace Linq2
07 {
08 class Employee
09 {
10
public string 員工編號 { get; set; }
11
public string 姓名 { get; set; }
12
public string 信箱 { get; set; }
13
public int 薪資{get; set;}
14
public DateTime 雇用日期{get; set;}
15
public bool 是否已婚 { get; set; }
16 }
17 }
24
堅毅誠樸
第十六章 LINQ 資料查詢技術
Step3 設計 Form1.cs 表單輸出入介面
25
堅毅誠樸
第十六章 LINQ 資料查詢技術
FileName : Form1.cs
01 Employee[] emp = new Employee[5];
02 // 表單載入時執行此事件處理函式
03 private void Form1_Load(object sender, EventArgs e)
04 {
05 emp[0] = new Employee { 姓名 = "菜一林", 信箱 = "[email protected]",
是否已婚 = false, 員工編號 = "E001",
雇用日期 = new DateTime(2007, 1, 1), 薪資 = 65000 };
06 emp[1] = new Employee { 姓名 = "羅字祥", 信箱 = "[email protected]",
是否已婚 = true, 員工編號 = "E002",
雇用日期 = new DateTime(2006, 1, 1), 薪資 = 75000 };
07 emp[2] = new Employee { 姓名 = "周傑輪", 信箱 = "[email protected]",
是否已婚 = false, 員工編號 = "E003",
雇用日期 = new DateTime(2008, 1, 1), 薪資 = 55000 };
08 emp[3] = new Employee { 姓名 = "王建名", 信箱 = "[email protected]",
是否已婚 = true, 員工編號 = "E004",
雇用日期 = new DateTime(2006, 5, 3), 薪資 = 105000 };
26
堅毅誠樸
第十六章 LINQ 資料查詢技術
09
10
11
12
13
14
15
16
17 }
emp[4] = new Employee { 姓名 = "李五六", 信箱 = "[email protected]",
是否已婚 = false, 員工編號 = "E005",
雇用日期 = new DateTime(2008, 5, 2), 薪資 = 45000 };
richTextBox1.Text = "編號\t姓名\t信箱\t\t\t雇用日期\t薪資\t是否已婚\n";
richTextBox1.Text +=
"========================================================\n";
var result = from p in emp
select p;
foreach (var p in result)
{
richTextBox1.Text += p.員工編號 + "\t" + p.姓名 + "\t" + p.信箱 + "\t" +
p.雇用日期.ToShortDateString() + "
\t" +
p.薪資.ToString() + "\t" + p.是否已婚.ToString() + "\n";
}
27
堅毅誠樸
第十六章 LINQ 資料查詢技術
18 // 按員工編號鈕執行此事件處理函式
19 private void btnEmpId_Click(object sender, EventArgs e)
20 {
21 richTextBox1.Text = "編號\t姓名\t信箱\t\t\t雇用日期\t薪資\t是否已婚\n";
22 richTextBox1.Text +=
"========================================================\n";
23 var result = from p in emp
orderby p.員工編號 ascending
select p;
24 foreach (var p in result)
25 {
26
richTextBox1.Text += p.員工編號 + "\t" + p.姓名 + "\t" + p.信箱 + "\t" +
p.雇用日期.ToShortDateString() + "
\t" +
p.薪資.ToString() + "\t" + p.是否已婚.ToString() + "\n";
27 }
28 }
28
堅毅誠樸
第十六章 LINQ 資料查詢技術
29 // 按薪資鈕執行此事件處理函式
30 private void btnSalary_Click(object sender, EventArgs e)
31 {
32 richTextBox1.Text = "編號\t姓名\t信箱\t\t\t雇用日期\t薪資\t是否已婚\n";
33 richTextBox1.Text +=
"========================================================\n";
34 var result = from p in emp
orderby p.薪資 ascending
select p;
35 foreach (var p in result)
36 {
37
richTextBox1.Text += p.員工編號 + "\t" + p.姓名 + "\t" + p.信箱 + "\t" +
p.雇用日期.ToShortDateString() + "
\t" +
p.薪資.ToString() + "\t" + p.是否已婚.ToString() + "\n";
38 }
39 }
29
堅毅誠樸
第十六章 LINQ 資料查詢技術
40 // 按雇用日期鈕執行此事件處理函式
41 private void btnDate_Click(object sender, EventArgs e)
42 {
43
richTextBox1.Text = "編號\t姓名\t信箱\t\t\t雇用日期\t薪資\t是否已婚\n";
44
richTextBox1.Text +=
"========================================================\n";
45
var result = from p in emp
orderby p.雇用日期 ascending
select p;
46
foreach (var p in result)
47
{
48
richTextBox1.Text += p.員工編號 + "\t" + p.姓名 + "\t" + p.信箱 + "\t" +
p.雇用日期.ToShortDateString() + "
\t" +
p.薪資.ToString() + "\t" + p.是否已婚.ToString() + "\n";
49
}
50 }
30
堅毅誠樸
第十六章 LINQ 資料查詢技術
51 // 按單筆查詢鈕執行此事件處理函式
52 private void btnSelEmpById_Click(object sender, EventArgs e)
53 {
54 richTextBox1.Text = "";
55 var result = from p in emp
where p.員工編號 == txtEmpId.Text
select new
{
p.員工編號, p.姓名, p.信箱, p.薪資
};
61 if (result.Count() == 0)
//判斷查詢的結果是否為零筆
62 {
63
MessageBox.Show("沒有此員工");
64
return;
65 }
66 foreach (var p in result)
67 {
68
richTextBox1.Text += "編號:" + p.員工編號;
69
richTextBox1.Text += "\n姓名:" + p.姓名;
70
richTextBox1.Text += "\n信箱:" + p.信箱;
71
richTextBox1.Text += "\n薪資:" + p.薪資;
72 }
73 }
31
堅毅誠樸
第十六章 LINQ 資料查詢技術
16.4 LINQ To SQL

LINQ to SQL 的技術是以 ADO .NET 資料提供者模型所提供的
服務為基礎。

LINQ to SQL是物件模型(Object Model)與關連式資料庫
Mapping的技術

簡單說就是資料庫、資料表、資料列、資料欄位、主鍵及關聯
都可直接對應至程式設計中的物件,在撰寫新增、修改、刪除
及查詢資料庫程式時,完全不用撰寫 SQL 語法的 SELECT、
INSERT、DELETE、UPDATE 陳述式,可不用處理資料庫
程式設計的細節,以直覺物件導向程式來直接撰寫資料庫應用
程式。

目前 LINQ to SQL 技術只支援微軟的 SQL Server 資料庫,
並不支援其他廠商資料庫。
32
堅毅誠樸
第十六章 LINQ 資料查詢技術
下表即是 LINQ to SQL 物件模型對應至資料庫的物件
 類別對應至資料表
 類別屬性對應至資料行(資料欄位)
 類別方法對應至SQL Server資料庫函式或預存程序。
33
堅毅誠樸
第十六章 LINQ 資料查詢技術
使用 ORM 設計工具動態產生可對應至Database.mdf
實體資料庫的 DataClasses1DataContext 類別程式碼
透過 DataClasses1DataContext 類別產生的dc物件及
配合LINQ to SQL查詢運算式來查詢「員工」資料表,
可依員工編號、薪資、雇用日期做遞增排序,並將排序
結果顯示dataGridView1;可查詢最高薪資、最低薪資
平均薪資及薪資加總。也可在文字方塊內輸入要查詢的
員工編號並按
鈕來查詢是否有該位員工。
34
堅毅誠樸
第十六章 LINQ 資料查詢技術
35
堅毅誠樸
第十六章 LINQ 資料查詢技術
Step1 建立名稱為 Linq3 的 Windows Form 應用程式專案。
Step2 連接資料來源
36
堅毅誠樸
第十六章 LINQ 資料查詢技術
37
堅毅誠樸
第十六章 LINQ 資料查詢技術

Step3 建立 LINQ to SQL 類別檔
38
堅毅誠樸
第十六章 LINQ 資料查詢技術
39
堅毅誠樸
第十六章 LINQ 資料查詢技術
40
堅毅誠樸
第十六章 LINQ 資料查詢技術
41
堅毅誠樸
第十六章 LINQ 資料查詢技術
FileName : Linq3.sln
01 DataClasses1DataContext dc = new DataClasses1DataContext();
02 // 表單載入時執行此事件處理函式
03 private void Form1_Load(object sender, EventArgs e)
04 {
05
var result1 = from p in dc.員工
select p;
06
dataGridView1.DataSource = result1;
08
var result2 = from p in dc.員工
select p.薪資;
09
lblShow.Text = "最高薪資:" + result2.Max().ToString() +
"\n最低薪資:" + result2.Min().ToString() +
"\n平均薪資:" + result2.Average().ToString() +
"\n薪資加總:" + result2.Sum ().ToString();
10
lblShow.BorderStyle = BorderStyle.Fixed3D;
11
lblShow.BackColor = Color.Pink;
12 }
42
堅毅誠樸
第十六章 LINQ 資料查詢技術
13 // 按員工編號鈕執行此事件處理函式
14 private void btnEmpId_Click(object sender, EventArgs e)
15 {
16 var result = from p in dc.員工
orderby p.員工編號 ascending
select p;
17 dataGridView1.DataSource = result;
18 }
19 // 按薪資鈕執行此事件處理函式
20 private void btnSalary_Click(object sender, EventArgs e)
21 {
22 var result = from p in dc.員工
orderby p.薪資 ascending
select p;
23 dataGridView1.DataSource = result;
24 }
43
堅毅誠樸
第十六章 LINQ 資料查詢技術
25 // 按雇用日期鈕執行此事件處理函式
26 private void btnDate_Click(object sender, EventArgs e)
27 {
28 var result = from p in dc.員工
orderby p.雇用日期 ascending
select p;
29 dataGridView1.DataSource = result;
30 }
31 // 按單筆查詢鈕執行此事件處理函式
32 private void btnSelEmpById_Click(object sender, EventArgs e)
33 {
34 var result = from p in dc.員工
where p.員工編號 == txtEmpId.Text
select p;
37 if (result.Count() == 0)
38 {
39
MessageBox.Show("沒有此員工");
40
return;
41 }
42 foreach (var p in result)
43 {
44
MessageBox.Show("編號:" + p.員工編號 + "\n姓名:" + p.姓名 +
"\n信箱:" + p.信箱 + "\n薪資:" + p.薪資);
45 }
46 }
44
堅毅誠樸