Tải bản đầy đủ (.pdf) (27 trang)

Tuan06 linq basic

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.1 MB, 27 trang )

10/6/2019

Lập trình Ứng dụng quản lý
LINQ cơ bản

Nội dung
 Generic Delegates

 Anonymous Methods
 Lambda Expressions
 Extension Method
 Query Expression
 Khái niệm LINQ
 LINQ Query

1


10/6/2019

Nội dung
 Generic Delegates
 Anonymous Methods
 Lambda Expressions
 Extension Method
 Query Expression
 Khái niệm LINQ
 LINQ Query

Generic Delegates
 Tương tự với method, delegate cũng có thể cài



đặt theo kiểu generic (nhằm làm tham số hàm
chung nhất cho một số trường hợp).
public delegate void MyDelegate<T>(T param);

 Trong .NET được khai báo sẵn một số các

generic delegate như: Predicate<T>,
Action<T>, Comparison<T>,…

2


10/6/2019

Generic Delegates thông dụng
 Predicate<T> được sử dụng để kiểm tra các giá








trị có thỏa mãn một điều kiện nào đó khơng và trả
về kiểu bool.
Action<T> sử dụng để thực hiện các hành động
với đối tượng mà ta truyền vào và không trả về
giá trị nào cả.

Comparison<T> dùng để so sánh hai đối tượng
cùng kiểu, thường sử dụng trong các trường hợp
sắp xếp.

Ví dụ thường gặp nhất là các phương thức tĩnh
được cung cấp trong class Array.

Ví dụ
 class Array
 Phương thức tìm kiếm
T[] Array.FindAll<T>(T[] array, Predicate<T>
match)
 Phương thức duyệt mảng
void Array.ForEach<T>(T[] array, Action<T> action)
 Phương thức sắp xếp
void Array.Sort<T>(T[] array, Comparison<T> comparison)

3


10/6/2019

Cách sử dụng
bool FuncPredicate(int value)
{
return value % 2 == 0;
}
StringBuilder sb = new StringBuilder();
void FuncAction(int value)
{

sb.AppendFormat("{0}, ", value);
}
int FuncComparison(int x, int y)
{
return x.CompareTo(y);
}
void funcTest()
{
int[] arrInt = new int[] { 3, 5, 7, 2, 10, 43, 12, 34 };
//sử dụng Predicate
int[] arrTemp = Array.FindAll<int>(arrInt, new
Predicate<int>(FuncPredicate));
//sử dụng Action
Array.ForEach(arrInt, new Action<int>(FuncAction));
//sử dụng Comparison
Array.Sort(arrInt, new Comparison<int>(FuncComparison));
}

Generic Delegates Action<> và Func<>
 Từ C# 3.0, Microsoft cung cấp một kiểu delegate

mới linh hoạt và tiện dụng hơn là Action, Func.
 Action, Func cho phép khai báo và tạo ra các
dạng delegate với số lượng tham số và kiểu trả
về khác nhau, tương tự như khi tạo ra một
method.
 Action, Func được dùng chủ yếu để tạo và lưu
trữ một anonymous method ngắn gọn bằng
lambda expression và được sử dụng như
những method thông thường.


4


10/6/2019

Syntax
 Cú pháp để sử dụng Action, Func là viết các kiểu

của tham số và giá trị trả về vào cặp ngoặc ‘<>’,
theo sau từ khóa Action, Func.
Action<T, T, ..., T>
Func<T, T, ..., TResult>
 Trong đó T là các kiểu của tham số cần truyền vào và

TResult là kiểu của giá trị trả về.
 Lưu ý là Func yêu cầu ít nhất một tham số trong cặp ‘<>’,
tức là phải có kiểu trả về. Khơng để đặt void hay để một
cặp ngoặc ‘<>’ rỗng khi dùng Func.

Ví dụ
static void DisplayMsg(string msg,
Func<string, ConsoleColor> func,
Action<string, int> action)
{
ConsoleColor previous = Console.ForegroundColor;
if (func != null)
{
Console.ForegroundColor = func(msg);
}

int count = (new Random()).Next(2, 5);
if (action != null)
{
action(msg, count);
}
Console.ForegroundColor = previous;
}

5


10/6/2019

Các method
 Cho Func<string, ConsoleColor>

static ConsoleColor GetColor(string msg)
{
if (msg.Length >= 10)
return ConsoleColor.Red;
if (msg.Length >= 7)
return ConsoleColor.Yellow;
if (msg.Length >= 4)
return ConsoleColor.Blue;
return ConsoleColor.White;
}
 Cho Action<string, int>

static void PrintMsg(string msg, int count)
{

for (int i = 0; i < count; i++)
{
Console.WriteLine(msg);
}
}

Hàm main
static void Main(string[] args)
{
var func = new Func<string, ConsoleColor>(GetColor);
var action = new Action<string, int>(PrintMsg);
DisplayMsg("Test
Test", func, action);
}

6


10/6/2019

Nội dung
 Generic Delegates

 Anonymous Methods
 Lambda Expressions
 Extension Method
 Query Expression
 Khái niệm LINQ
 LINQ Query


Anonymous Methods
 Anonymous method (tạm dịch là phương thức vô

danh) là phương thức không có tên được khai báo
với từ khóa delegate.
 Anonymous method cho phép tạo ra các hành động
cho một delegate với cách viết inline.
 Cụ thể
delegate void DelTest(int value);
void funcTest()
{
DelTest dt = delegate(int value)
{
//...
};
}

7


10/6/2019

Truy xuất biến cục bộ
 Anonymous method không thể truy xuất tham

số ref hay out của method cha.
 Anonymous method khơng được có biến cục bộ
cùng tên với biến của method cha.
 Anonymous method có thể truy xuất thành phần
dữ liệu của class chứa nó.

 Anonymous method có thể dùng tên biến chung
với thành phần dữ liệu của class chứa nó.

Áp dụng trong các Generic Delegate
static void funcTest()
{
var sb = new StringBuilder();
int[] arrInt = new int[] { 3, 5, 7, 2, 10, 43, 12, 34 };
//sử dụng Predicate
int[] arrTemp = Array.FindAll<int>(arrInt,
delegate (int value) {
return value % 2 == 0;
});
//sử dụng Action
Array.ForEach(arrInt, delegate (int value) {
sb.AppendFormat("{0}, ", value);
});
//sử dụng Comparison
Array.Sort(arrInt, delegate (int x, int y) {
return x.CompareTo(y);
});
}

8


10/6/2019

Áp dụng cho callback method
static void Main(string[] args)

{
var c = new CTest();
c.EvtMyHandler += delegate (object sender, MyEventArgs e)
{
Console.WriteLine(e.msg);
};
c.EvtMyHandler += delegate (object sender, MyEventArgs e)
{
var str = e.msg.ToUpper();
Console.WriteLine(str);
};
}

Nội dung
 Generic Delegates

 Anonymous Methods

 Lambda Expressions
 Extension Method
 Query Expression
 Khái niệm LINQ
 LINQ Query

9


10/6/2019

Lambda Expressions

 Có từ C# 3.0
 Có thể nói so với anonymous method, lambda

expression được coi là một sự cải tiến đáng giá từ
phiên bản C# 2.0 lên C# 3.0.
 Khi dùng anonymous method có thể tạo các hàm inline nhằm hạn chế việc khai báo các hàm riêng lẻ
không cần thiết, giúp mã lệnh ngắn gọn hơn.
 Với lambda expression thì có thể viết ngắn gọn và
dễ dàng hơn nhờ việc cung cấp toán tử và cú pháp
mới, đồng thời thể hiện sự “thông minh” của
compiler bằng cách tự nhận diện kiểu của dữ liệu.
 Ngồi ra, đây cịn là kĩ thuật để tạo ra các kiểu
expression tree.

Syntax
 Dạng của Lambda Expression như sau:

(input parameters) => expression
 Dấu mở và đóng ngoặc là tùy chọn trong trường hợp chỉ

có 1 tham số, ngược lại nó là bắt buộc.
 Nếu có nhiều hơn 1 tham số thì chúng sẽ được phân
cách bằng dấu phẩy (,).
 Kiểu dữ liệu của các tham số có thể được khai báo
tường minh hoặc khơng. Nếu khơng khai báo, trình biên
dịch sẽ tự xác định kiểu, tuy nhiên trong một số trường
hợp, cần phải chỉ rõ kiểu dữ liệu.
//sẽ báo lỗi
s => s.Length;
//cần khai báo kiểu dữ liệu

(string s) => s.Length;

10


10/6/2019

Ví dụ
 Anonymous method
var list = new List<int> { 3, 5, 7, 2, 10, 43, 12, 34 };
var evens = list.FindAll(delegate (int i)
{
return (i % 2) == 0;
});

 Dạng đầy đủ
var evens = list.FindAll((int i) => { return i % 2 == 0; });

 Dạng rút gọn
var evens = list.FindAll((int i) => ((i % 2) == 0));
var evens = list.FindAll(i => (i % 2) == 0);

Đặc điểm
 Kiểu dữ liệu của tham số có thể khai báo tường

minh hoặc khơng tường minh.
 Có thể sử dụng {} hoặc () để bọc khối lệnh. Có
sự khác biệt giữa 2 loại???
 Có thể loại bỏ cặp dấu bọc khối lệnh khi không
cần thiết.


11


10/6/2019

Truyền tham số trong Lambda Expression
 Nhiều tham số
var c = new CTest();
c.EvtMyHandler += (sender, e) =>
{
Console.WriteLine(e.msg);
};

 Khơng có tham số
Func<int> func = () => (new Random()).Next();

Nội dung
 Generic Delegates

 Anonymous Methods
 Lambda Expressions

 Extension Method
 Query Expression
 Khái niệm LINQ
 LINQ Query

12



10/6/2019

Extension Methods
 Có từ C# 3.5
 Cho phép tạo thêm phương thức cho 1 class mà

không cần tạo class kế thừa. Nói cách khác là
thực thi 1 hàm như là thể hiện phương thức của
lớp đối tượng khác.
 Được dùng trong nhu cầu cần thêm một số các
hành xử của đối tượng mà không thể thay đổi
kiểu của đối tượng.
 Có thể gọi phương thức từ đối tượng null của
class.

Cách tạo Extension Method
 Phương thức để tạo Extension Method phải thỏa các

điều kiện:

 Là phương thức static của một static class khơng kế thừa,

khơng generic.
 Phải có ít nhất 1 tham số đầu vào.
 Tham số đầu tiên phải có từ khóa this theo trước.
 Tham số đầu tiên khơng được kèm theo các từ khóa như out,

ref ,… khơng được là kiểu pointer.


 Ví dụ:
public static class MyExtensionMethod
{
//extension method cho class object
public static bool isNull(this object obj)
{
return obj == null;
}
}

13


10/6/2019

Ví dụ tình huống sử dụng
 Có class SinhVien
public class SinhVien
{
public string HoTen{get;set;}
public int NamSinh{get;set;}
}

 Hàm sử dụng class SinhVien
public class SVUlti
{
public static SinhVien SVLonTuoiHon(SinhVien sv1, SinhVien sv2)
{
return (sv1.NamSinh > sv2.NamSinh) ? sv2 : sv1;
}

}

 Bây giờ vẫn sử dụng hàm đã có mà cần thêm phương

thức lấy họ của Sinh viên?

 Tạo Extension method cho class SinhVien đáp ứng yêu cầu

public static class MyExtensionMethod
{
//extension method cho class SinhVien
public static string LayHoSV(this SinhVien sv)
{
int idx = sv.HoTen.IndexOf(' ');
if (idx == -1)
idx = sv.HoTen.Length;
return sv.HoTen.Substring(0, idx);
}
}
 Khi đó có thể sử dụng như sau
var sv1 = new SinhVien { HoTen = "Nguyen Van A", NamSinh = 1992 };
var sv2 = new SinhVien { HoTen = "Tran Thi B", NamSinh = 1993 };
var hoSV = SVUlti.SVLonTuoiHon(sv1, sv2).LayHoSV();

14


10/6/2019

Tạo extension method khác

public static List<string> LayDSHoSV(this List<SinhVien> ds)
{
var l = new List<string>();
foreach (SinhVien sv in ds)
{
l.Add(sv.LayHoSV());
}
return l;
}
public static List<SinhVien> LayDSSVLonTheoNam(this List<SinhVien> ds, int nam)
{
var l = new List<SinhVien>();
foreach (SinhVien sv in ds)
{
if (sv.NamSinh < nam)
{
l.Add(sv);
}
}
return l;
}

Mức độ ưu tiên của Extension Method
 Extension method có độ ưu tiên thấp hơn Instance

method. Điều đó có nghĩa là nếu có sự xuất hiện của
Instance method thì nó ln được gọi thay vì Extension
method.
 Ví dụ nếu trong class SinhVien ở trên có phương thức
LayHoSV ngay trong class (instance method) thì nó luôn

được sử dụng.
public class SinhVien
{
public string HoTen{get;set;}
public int NamSinh{get;set;}
public string LayHoSV()
{
return "Ho";
}
}

15


10/6/2019

Extension methods trong .NET 3.5
 Được sử dụng chủ yếu là cho LINQ.
 Chứa đựng chủ yếu trong 2 class chính là:

Enumerable và Queryable.
 Hầu hết các phương thức từ Enumerable là xử
lý trên IEnumerable<T> và các phương thức từ
Queryable là xử lý trên IQueryable<T>.
 Không phải tất cả các phương thức của
Enumerable và Queryable đều là Extension
method.

Ví dụ
 Phương thức Range của Enumerable tạo mảng


các số int theo dạng IEnumerable<int>. Đây là
phương thức tĩnh của chính class.
//tạo mảng {0, 1, 2, 3,..., 9}
IEnumerable<int> lstInt = Enumerable.Range(0, 10);
//sử dụng phương thức mở rộng
lstInt = lstInt.Reverse();

 Phương thức Reverse là extension method

của class IEnumerable<T> được cài đặt
trong Enumerable. Do đó có thể viết liền như
sau:
IEnumerable<int> lstInt = Enumerable.Range(0, 10)
.Reverse();

16


10/6/2019

Phương thức mở rộng Where
 Là extension method cho class IEnumerable<T>

được cài đặt trong Enumerable.
 Cung cấp khả năng lọc (filter) dữ liệu theo điều
kiện mong muốn (Predicate).
 Xem cách sử dụng:
//lấy ra các số lẻ của mảng và đảo mảng
var lstInt = Enumerable.Range(0, 10)

.Where(x => x % 2 != 0)
.Reverse();

 Cài đặt thực tế của extension method Where
public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
Func<T, bool> predicate)
{
if (source == null || predicate == null)
{
throw new ArgumentNullException();
}
return WhereImpl(source, predicate);
}
private static IEnumerable<T> WhereImpl<T>(IEnumerable<T> source,
Func<T, bool> predicate)
{
foreach (T item in source)
{
if (predicate(item))
{
yield return item;
}
}
}

17


10/6/2019


Phương thức mở rộng Select
 Là phương thức thông dụng nhất dùng lấy dữ

liệu trong IEnumerable<T> được cung cấp
extension bởi Enumerable.
 Nó xử lý trên IEnumerable<TSource> và đưa dữ
liệu vào IEnumerable<TResult> bằng cách dùng
delegate Func<TSource, TResult>.
 Ví dụ:
//lấy ra các đối tượng từ số lẻ của mảng và đảo mảng
var lstInt = Enumerable.Range(0, 10)
.Where(x => x % 2 != 0)
.Reverse()
.Select(x => new { Original = x,
Sqrt = Math.Sqrt(x) });

Phương thức mở rộng OrderBy
 Cung cấp khả năng sắp xếp dữ liệu theo tiêu chí

được lựa chọn.
 Bao gồm các phương thức: OrderBy,
OrderByDescending, ThenBy,
ThenByDescending.
 Ví dụ
//lấy ra các đối tượng từ mảng số và sắp xếp
var dsSN = Enumerable.Range(-5, 11)
.Select(x => new { Org = x, Sqr
= x * x })
.OrderBy(x => x.Sqr)
.ThenByDescending(x => x.Org);


18


10/6/2019

Nội dung
 Generic Delegates
 Anonymous Methods
 Lambda Expressions
 Extension Method

 Query Expression
 Khái niệm LINQ
 LINQ Query

Query Expression
 Ra đời cùng với C# 3.5 nhằm cung cấp cú pháp

(syntax) ngôn ngữ tích hợp (language-integrated) cho
các lệnh truy vấn tương tự như ngôn ngữ truy vấn
quan hệ và phân cấp SQL, XQuery.
 Query expression bắt đầu với mệnh đề from và kết
thúc bởi mệnh đề select hoặc group. Nói cách khác
là luôn bắt đầu với một nguồn dữ liệu và kết thúc bởi
các dữ liệu được lựa chọn.
 Ví dụ
var lst = Enumerable.Range(0, 11);
var resultQ = from i in lst
where i % 2 == 0

select i;

19


10/6/2019

Compiler translations
 Là cơ sở nền tảng của Query expression.
 Mục tiêu là thông dịch cú pháp Query expression

sang C# code bình thường.
 Ví dụ câu lệnh query expression ở ví dụ trước sẽ
được thơng dịch về dạng
var lst = Enumerable.Range(0, 11);
var resultQ = lst.Where(i => i % 2 == 0)
.Select(i => i);

 Xét cụ thể hơn trong ví dụ sau:

 Có class Test với phương thức Select
public class Test<T>
{
public Test<U> Select<U>(Func<T, U> selector)
{
MyExtensionMethod.sb.AppendLine("Select called...");
return new Test<U>();
}
}


 Xây dựng extension method
public static class MyExtensionMethod
{
public static StringBuilder sb = new StringBuilder();
//extension method cho class Test
public static Test<T> Where<T>(this Test<T> test,
Func<T, bool> predicate)
{
sb.AppendLine("Where called...");
return test;
}
}

20


10/6/2019

 Sử dụng query expression
MyExtensionMethod.sb.Clear();
var temp = new Test<int>();
var rs = from test in temp
where test.ToString() == ""
select "test";

 Bản chất sau đó được thơng dịch về
rs = temp.Where(x => x.ToString() == "")
.Select(x => "test");

 Kết quả trong sb là:


“Where called…
Select called…”
và đối tượng rs là Test<string>.

Query Operators
 Bản chất là các extension method
Category
Restriction
Projection
Partitioning
Join
Concatenation
Ordering
Grouping
Set

Where
Select, SelectMany
Take, Skip, TakeWhile, SkipWhile
Join, GroupJoin
Concat
OrderBy / ThenBy, Reverse
GroupBy
Distinct, Union, Intersect, Except

Conversion

ToSequence, ToArray, ToList, ToDictionary, ToLookup, OfType, Cast


Equality

EqualAll
First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault,
ElementAt, ElementAtOrDefault, DefaultIfEmpty
Range, Repeat, Empty
Any, All, Contains
Count, LongCount, Sum, Min, Max, Average, Aggregate

Element
Generation
Quantifiers
Aggregate

Operator

21


10/6/2019

Nội dung
 Generic Delegates
 Anonymous Methods
 Lambda Expressions
 Extension Method
 Query Expression

 Khái niệm LINQ
 LINQ Query


Khái niệm LINQ
 LINQ đọc là LINK, không phải LIN-QUEUE

 LINQ: Language Integrated Query

 Ra đời từ phiên bản .Net 3.5 gắn liền với

Extension Method và các chức năng lập trình
mới, LINQ đã trở thành “cầu nối để xóa đi
khoảng cách giữa hai thế giới: object và data”.
 LINQ cho phép developer thực hiện truy vấn

trên nhiều dạng dữ liệu trong .NET
 .NET Objects (List, Queue, Array, …)

 Database (DLINQ)
 XML (XLINQ)
 Parallel LINQ (PLINQ)

22


10/6/2019

Phân loại LINQ
 LINQ được chia thành ba loại chính dựa vào đối

tượng sử dụng
 LINQ to Objects

 LINQ to XML
 LINQ-enabled ADO.NET (LINQ to SQL, LINQ to

DataSet và LINQ to Entities)
 Có thể bổ sung provider để mở rộng các nguồn dữ
liệu mà LINQ có thể truy vấn

Kiến trúc LINQ
 Kiến trúc

23


10/6/2019

Syntax
 LINQ syntax
 Query syntax

var q1 = from i in arrI
where i % 2 == 0
select i;
 Method syntax hay Lambda syntax
var q2 = arrI.Where(i => i % 2 == 0)
.Select(i => i);

Cơ sở của LINQ
 Nền tảng của LINQ dựa vào các yếu tố quan

trọng sau

 Implicitly typed local variables (cho phép khai

báo biến với kiểu dữ liệu không tường minh)
 Object/collection initialization syntax (cú pháp
mới khởi tạo đối tượng, danh sách)
 Lambda Expressions
 Extension methods
 Anonymous types

24


10/6/2019

Expression Tree
 Vai trò Expression Tree trong LINQ

Nội dung
 Generic Delegates

 Anonymous Methods
 Lambda Expressions
 Extension Method
 Query Expression
 Khái niệm LINQ

 LINQ Query

25



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×