Categorieën: Alle - 方法

door 余小章 's 6 jaren geleden

1051

LINQ

LINQ 是一種整合在語言中的查詢技術,提供了兩種主要的查詢語法:方法架構查詢和查詢運算式。方法架構查詢使用擴充方法來實作標準查詢運算子,例如 OrderBy、Where、Join 等,並且採用 Fluent Pattern 的實現方式。查詢運算式則類似 SQL 的查詢語法,使用小寫關鍵字來進行操作,如 orderby、select、group by 等。使用 LINQPad 可以立即執行查詢並觀察結果,如 Dump 方法可以將資料即時印出來,還可以建立資料庫連線和匯出 SQL 語法。

LINQ

LINQ Language-Integrated Query

案例

SQL的Like
攤牌,Inter Join
手動建立以下資料結構,然後印出來
咱們來分組練習
為了証明真的沒有問題,不是嘴炮
進入這個主題之前,先問大家一個問題,以上所講的有沒有問題?
浮現式設計是一種敏捷技術,強調在開發過程中不斷演進,最後產出高品質的產品。

PLINQ (Parallel LINQ)

AsParallel()
在許多情況下,PLINQ 都能更有效地使用主機電腦上的所有可用核心,而大幅提升 LINQ to Objects 查詢的速度。 此效能提升後,桌面運算效能也可隨之提高。

Linq To Dataset

如果可以,請拋棄 Datatable Object,進化成 Entity Framework
實作強型別的 Dataset Sample:SimpleLinqToDataset
實作強型別的 Datatable Sample:MyStrongDatatable
弱型別的DataTable Sample:MyDatatable

AsEnumerable vs AsQueryable

對 LINQ to SQL 還有 LINQ to Entities 來說
AsQueryable 方法,會將查詢語句翻成 T-SQL 後再向SQL發送查詢命令
AsEnumerable 方法,是將 SQL 資料載入至記憶體,再進行查詢
已經有 AsEnumerable() 了,為什麼還要有 AsQueryable()?
一堆物件實作來實作去,這感覺好像在鬼打牆
它們是幹嘛的?
IQueryable 實作 IEnumerable
AsQueryable(),回傳 IQueryable
AsEnumerable(),回傳 IEnumerable
要用 AsEnumerable 還是 AsQueryable?

LINQ 語法介紹

Linq Samples and the Sample Query Explorer
兩種查詢語法
方法架構查詢(Method-Based Query):「標準查詢運算子」 (Standard Query Operator) ,標準查詢運算子是以稱為「擴充 方法」(Extension Method) 的一種新方法來實作。

Select()

OrderByDescending()

Join()

OrderBy()

Where()

IEnumerable.Where(..).Where(..).Select(..).Whers(..)

它是 Fluent Pattern 的一種實現

查詢運算式(Query Expression):類似 SQL 的查詢語法。

select |select new..into

orderby

descending

ascending

join [inner object] in [inner collection] on [outer Key] equals [inner Key] into [param] from [object] in [param].DefaultIfEmpty()

join [inner object] in [inner collection] on [outer Key] equals [inner Key]

group [collection] by [condition | column] into [param]

let [param] = value

where [Predicate condition]

from [outer object] in [outer collection]

關鍵字都是小寫

兩種執行模式
立即執行 (Forcing Immediate Execution)

Generation Operators

Empty

Repeat

Range

Aggregate Operators

Aggregate

Min, Max, Sum, and Average

Count and LongCount

Quantifier Operators

Contains

All

Any

Element operators

ElementAt, ElementAtOrDefault

DefaultIfEmpty

Single, SingleOrDefault

Last, LastOrDefault

First, FirstOrDefault

Equality Operator

SequenceEqual

To . . . Operators

ToLookup

ToList

ToArray

延遲執行 (Deferred Execution)

有哪些方法?

Conversion operators

Of Type

Cast

AsQueryable

AsEnumerable

Grouping Operator

GroupBy

Ordering Operators

Reverse

ThenBy

OrderByDescending

OrderBy

Partitioning Operators

SkipWhile

TakeWhile

Skip

跳過指定數量的元素,超出不引發例外

Take

取得指定數量的元素,超出不引發例外

Concatenation Operator

Intersect

交集

Except

差集

Union

聯集,剔除重複

Concat

不需要比較子

聯集,保留全部

參考型別要實作比較子IEqualityComparer

連結相同物件

Join Operators

Zip

以集合較少數的物件,連接另外一個集合

GroupJoin

要處理null

Outer Join

Join

用key連接不同的物件,型別要一樣

Inner Join

連接不同物件

Restriction Operator

Where

多個Where連結同等於And

可呼叫另一個函數

過濾符合條件的內容

Projection Operators

SelectMany

把集合容器的內容壓平、攤開

Select

把結果轉成另外一個型別

取出需要的欄位

映射

查詢語法都是延遲執行 Select,Where,OrderBy...

偵錯觀察運行結果

延遲執行要等到實際驅動點時,調用立即執行的擴充方法或是foreach,才會執行原本 LINQ 該執行的動作

使用 LINQPad
Export
To SQL 語法
建立範例資料庫
Dump(),立即執行,將資料印出來
如何使用下載安裝範例
加入參考
建立資料庫連線 AdvantureWorks

LINQ背後的技術

沒有LINQ時排序怎麼做?
沒有 LINQ 時,用 DatatTable+DataView 排序?

強型別的 DataSet ,大都由工具產生出來的,很好, 但無法享用物件導向的特性,彈性不佳;可以手動實作,但很麻煩

弱型別的 DataTable,boxing/unboxing 會造成系統資源損耗

Sample:SimpleCompare
沒有 LINQ 時,物件排序要自己實作 ICompare
委派 (delegate)
擴充方法 (Extension Methods)
Fluent Interface Pattern
Sample:SimpleFluent
適合用在需要對一個相同物件進行大量設定或方法呼叫
用起來的效果跟 jQuery 的方法鏈一樣
由 Eric Evans 和 Martin Fowler 提出,它有三個特性:

透過回傳一個 void 內容 (簡單的說就是 null 或不回傳最後的物件內容) 結束。

物件會自我參考 (self-referential),且新的物件內容會和最後一個物件內容等價

透過調用方法來定義物件內容

以下內容出自 朱明中 老師
匿名方法 (Anonymous Method)
這一定是抄 JavaScript 的!
為了只需要用一次的方法,而建立類別實體和該方法
隱含型別 (var)

為什麼要有var?當型別無法由開發人員決定時,比如匿名型別
var被稱為隱含型別,在編譯時期宣告成隱含型別的變數,其真實型別由等號右邊的值型別所決定,所以它是強型別
var vs dynamic

dynamic 執行時期檢查,沒有 IntelliSense

var 編譯時期檢查,有 IntelliSense

匿名型别 (Anonymous Type)
Sample:MyAnonymousType
型別需要傳遞或重用時,不要用
匿名型別是強型別嗎?

它是!!

匿名型別是直接衍生自 物件,因此,無法轉換為 物件以外的任何型別的 類別 型別
從 Common Language Runtime 的角度來看,匿名型別與其他參考型別不同
匿名型別宣告方式 var person = new { Name = "A", Age = 12 };
為什麼要用匿名型別?

針對多個集合物件,運行交集、聯集、差集、分組、過濾..等操作,回傳的型別組合,可說是千變萬化。 若要針對該回傳型別定義具名型別,會花費相當多的時間,這時匿名型別可替開發人員省下不少時間

型別只需要用到一次

foreach
yield return

CLR 會幫你換成 IEnumerator 的實作方式

實作

List是實作 IEnumerable,IEnumerator

繼承 IEnumerator

調用MoveNext方法,移至下一筆資料

取得Current屬性

繼承 IEnumerable

調用GetEnumerator取得IEnumeration

Sample:SimpleForeach

Iterator Pattern?

我們希望把物件巡訪的順序 (iteration) 跟依序拿到物件後要作什麼事 (process) 分開

聚合物件" 就是指 .NET 的 Collection, List, Array 等這類物件。意思是你不需要管 collection 裡每一個物件是怎麼擺的,用什麼結構處理的,用什麼邏輯或演算法處理的,我就只管照你安排好的順序一個一個拿出來就好。 (摘自 安得魯)

毋須知曉聚合物件的內部細節,即可依序存取內含的每一個元素。 (摘自 物件導向設計模式 Design Patterns 中文版,葉秉哲 譯)

聚合物件" 就是指 .NET 的 Collection, List, Array 等這類物件。意思是你不需要管 collection 裡每一個物件是怎麼擺的,用什麼結構處理的,用什麼邏輯或演算法處理的,我就只管照你安排好的順序一個一個拿出來就好。

為什麼要有foreach?
for loop vs foreach
foreach vs LINQ
老實講,這很基礎,但又很無聊

Architecture

它們是怎麼做的?
簡單來說,就是 Provider 本身提供將資料,轉型成 IEnumerable 的功能
總而言之,到處都可以用 ,LINQ to AnyWhere
LINQ to Access
LINQ to JSON
LINQ to Querystring
LINQ to SharePoint
LINQ to Log
LINQ to CSV
LINQ to Excel
LINQ to LDAP
LINQ to SQLite
LINQ to JavaScript
微軟內建,如下圖:

目的

操作物件時,只需要知道 Provider 所提供的 CUD 的功能,不需要知道後端資料來源格式
一致性的『物件』『查詢語法』,不論是 SQL、MySQL、Oracle、XML、Collection、JSON

什麼是LINQ

LINQ 就是[整合至程式語言中的查詢敘述語法]
Query = 查詢
Integrated = 整合
Language=程式語言
LINQ 全名為 Language Integrated Query