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
堅毅誠樸