LINQ
Download
1 / 77

LINQ 基础教程 - PowerPoint PPT Presentation


  • 242 Views
  • Uploaded on

LINQ 基础 教程. LINQ 基础教程. 主讲人:李春涛 徐卫东. 学习目标. 1. 3. 2. LINQ 查询方法 及项目 中的应用. LINQ 基本概念的掌握. LINQ 进阶. 1. LINQ 基本概念的掌握. 设计、组织和协作. LINQ 是 Language Integrated Query 的 简称。 是 Visual Studio 2008 和 .NET Framework 3.5 版中一项突破性的创新,它在对象领域和数据领域之间架起了一座 桥梁。

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'LINQ 基础教程' - devlin


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

LINQ基础教程

LINQ基础教程

主讲人:李春涛 徐卫东


学习目标

1

3

2

LINQ查询方法及项目中的应用

LINQ基本概念的掌握

LINQ进阶


1

LINQ基本概念的掌握

设计、组织和协作


LINQ是Language Integrated Query的简称。是 Visual Studio 2008 和 .NET Framework 3.5 版中一项突破性的创新,它在对象领域和数据领域之间架起了一座桥梁。

微软在2007年,将LINQ作为.NET Framework 3.5的一部分正式发布,编写程序时可以得到很好的编译时语法检查,丰富的元数据,智能感知、静态类型等强类型语言的好处。


LINQ包括五个部分:LINQ to Objects、LINQ to DataSets、LINQ to SQL、LINQ to Entities、LINQ to XML。

LINQ to Objects在当前项目中应用最为频繁,是我们可以简单的对内存中所有基于IEnumerable<T>接口的数据源进行操作。

LINQ to SQL全称基于关系数据的.NET语言集成查询,用于以对象形式管理关系数据,并提供了丰富的查询功能。其建立于公共语言类型系统中的基于SQL的模式定义的集成之上,当保持关系型模型表达能力和对底层存储的直接查询评测的性能时,这个集成在关系型数据之上提供强类型。

LINQ to XML在System.Xml.LINQ命名空间下实现对XML的操作。采用高效、易用、内存中的XML工具在宿主编程语言中提供XPath/XQuery功能等。


LINQ的组成


LINQ相关的概念

扩展方法其实仅仅是语法糖,没有扩展方法,Linq的实现肯定不会再像现在这么优雅。从IL层面解释扩展方法的实现,它最终还是调用静态方法。匿名方法和Lambda表达式Lambda表达式将函数式编程风格带进了C#这种命令编程语言中,Lambda表达式可以编译成表达式树。匿名类型与隐式类型局部变量(var) 如果没有隐式类型局部变量,使用Linq查询的时候不会再像现在这么轻松吧.

var KeyPair1 = new { Key="yuyi",Value="Programer"};

匿名类型在编译阶段编译器就为匿名类型生成了类型的代码,但是生 成的是泛型版本的对象集合初始化器编译器会调用无参构造函数,然后为指定的属性赋值。对匿名类型来说是很有用的。


// 根据书籍分类获取书籍列表

var booksByCategory = from book in db.Books

where book.Category.Name == categoryName

select new

{

Title = book.Title,

Author = book.Author,

PublisherName = book.Publisher.Name,

PublishDate = book.PublishDate,

};

var booksByCategoryAndPage =

booksByCategory.Skip((pageNo - 1) * PAGE_SIZE).Take(PAGE_SIZE);

int pageCount = booksByCategory.Count() / PAGE_SIZE + 1;

gvBooks.DataSource = booksByCategoryAndPage;

gvBooks.DataBind();


2

LINQ进阶


LINQ查询执行的时机


LINQ的查询方式

1、Method Syntax,查询方法方式

主要利用System.Linq.Enumberable类中定义的扩展方法和Lambda表达式进行查询。

2、Query Syntax,查询语句方式

一种更接近SQL语法的查询方式,具有更好的可读性。


int[] numbers = new int[] { 6, 4, 3, 2, 9, 1, 7, 8, 5 };

var even = from number in numbers

where number % 2 == 0

orderby number descending

select number;

查询语句

两者的执行效果完全一样

int[] numbers = new int[] { 6, 4, 3, 2, 9, 1, 7, 8, 5 };

var even = numbers

.Where(p => p % 2 == 0)

.OrderByDescending(p => p)

.Select(p => p);

查询方法


表达式树

1、什么是表达式树?

它是一种抽象语法树或者说它是一种数据结构,通过解析表达式目录树,可以实现我们一些特定的功能,它是LINQ Provider的基础。


2、如何构造出表达式目录树

Expression<Func<int, int, int>> expression = (a, b) => a * b + 2;


为什么需要表达式树?

当我们在C#中编写一个查询表达式时,

它将返回一个IQueryable类型的值,在该类型中包含了

两个很重要的属性Expression和Provider

LINQ TO SQL 表达式树


3

LINQ查询方法及

项目中的应用

  • 一个Linq例子

  • Linq语法基础

  • Linq语法的本质

  • Linq语言要素


一个Linq例子


一个Linq例子

var words =

from word in "The quick brown fox jumps over the lazy dog".Split()

orderby word.ToUpper()

select word;


一个Linq例子

运行结果:


Linq语法基础


Linq语法基础

Where的声明:

public static IEnumerable<TSource> Where<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate )


Linq语法基础

运行结果:

string[] names = { "Tom", "Dick", "Harry" };

IEnumerable<string> filteredNames =

System.Linq.Enumerable.Where (names, n => n.Length >= 4);


Linq语法基础

运行结果:

String[] names = { "Tom", "Dick", "Harry" };

IEnumerable<string> result = names.Where(n=>n.Length >=4);


总结

Extension Method是一个定义在Static Class的一个特殊的Static Method。之所以说这个Static Method特别,是因为Extension Method不但能按照Static Method的语法进行调用,还能按照Instance Method的语法进行调用。


Linq语法的本质


Linq语法的本质

string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

IEnumerable<string> query1 = from name in names

where name.Contains("a")

orderby name.Length

select name.ToUpper();


Linq语法的本质

运行结果:


Linq语法的本质

string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

IEnumerable<string> query = names

.Where (n => n.Contains ("a"))

.OrderBy (n => n.Length)

.Select (n => n.ToUpper());


Linq语法的本质

运行结果:


Linq语法的本质

string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

IEnumerable<string> filtered = names.Where (n => n.Contains ("a"));

IEnumerable<string> sorted = filtered.OrderBy (n => n.Length);

IEnumerable<string> finalQuery = sorted.Select (n => n.ToUpper());


Linq语法的本质

string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

IEnumerable<string> filtered = names.Where (n => n.Contains ("a"));


Linq语法的本质

string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

IEnumerable<string> filtered = names.Where (n => n.Contains ("a"));

IEnumerable<string> sorted = filtered.OrderBy (n => n.Length);


Linq语法的本质

运行结果:


Linq语法的本质

string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

IEnumerable<string> filtered = names.Where (n => n.Contains ("a"));

IEnumerable<string> sorted = filtered.OrderBy (n => n.Length);

IEnumerable<string> finalQuery = sorted.Select (n => n.ToUpper());


Linq语法的本质

运行结果:


总结

Linq的语法,其实就是调用“扩展方法”的语法糖,Linq语句,最终都会转换成对相应的“扩展方法”的调用.


Linq语言要素


数据结构上的关联

public class Customer{

public string Name;

public string City;

public Order[] Orders;

}

public class Order{

public int Quantity;

public Product product;

}

public class Product{

public string ProductName;

}


数据结构上的关联

Order[] ordersA = {

new Order{Quantity = 10,product= new Product{ProductName = "PA1"}},

new Order{Quantity = 20,product = new Product{ProductName = "PA2"}},

new Order{Quantity =30,product = new Product{ProductName = "PA3"}}

};

Order[] ordersB = {

new Order{Quantity = 10,product= new Product{ProductName = "PB1"}},

new Order{Quantity = 20,product = new Product{ProductName = "PB2"}},

new Order{Quantity =30,product = new Product{ProductName = "PB3"}}

};

Customer[] Customers = {

new Customer{Name= "CA",City= "CityA",Orders =ordersA },

new Customer{Name = "CB",City = "CityB",Orders = ordersB}

};


数据结构上的关联

查询语句:

var query = from c in Customers

from o in c.Orders

select new { c.Name, o.Quantity, o.product.ProductName };

foreach(var item in query){

Console.WriteLine(item.ToString());

}


数据结构上的关联

运行结果:

{ Name = CA, Quantity = 10, ProductName = PA1 }

{ Name = CA, Quantity = 20, ProductName = PA2 }

{ Name = CA, Quantity = 30, ProductName = PA3 }

{ Name = CB, Quantity = 10, ProductName = PB1 }

{ Name = CB, Quantity = 20, ProductName = PB2 }

{ Name = CB, Quantity = 30, ProductName = PB3 }


数据结构上的关联2

var query = from c in Customers

from o in c.Orders

where o.Quantity == 20

select new { c.Name, o.Quantity, o.product.ProductName };

foreach (var item in query){

Console.WriteLine(item.ToString());

}


数据结构上的关联2

运行结果:

{ Name = CA, Quantity = 20, ProductName = PA2 }

{ Name = CB, Quantity = 20, ProductName = PB2 }


数据结构上的关联3

var query = from c in Customers

where c.Name.Contains("CA")

from o in c.Orders

where o.Quantity == 20

select new { c.Name, o.Quantity, o.product.ProductName };

foreach (var item in query){

Console.WriteLine(item.ToString());

}


数据结构上的关联3

运行结果:

{ Name = CA, Quantity = 20, ProductName = PA2 }


数据结构上的关联3

var query = from c in Customers

from o in c.Orders

where c.Name.Contains("CA")

where o.Quantity == 20

select new { c.Name, o.Quantity, o.product.ProductName };

varquery = from c in Customers

from o in c.Orders

where c.Name.Contains("CA") && o.Quantity == 20

select new { c.Name, o.Quantity, o.product.ProductName};

以上两种Linq效果相同


数据上的关联

public class Customer{

public string Name;

public string City;

}

public class Supplier{

public string City;

public string Name;

}


数据上的关联

Customer[] Customers = {

new Customer{City = "CA",Name = "CustA"},

new Customer{City = "CB",Name = "CustB"},

new Customer{City = "CC",Name = "CustC"},

new Customer{City = "CD",Name = "CustD"}

};

Supplier[] Suppliers ={

new Supplier{City = "CA" ,Name = "SA"},

new Supplier{City = "CB" ,Name = "SB"},

new Supplier{City = "CC" ,Name = "SC"},

new Supplier{City = "CC" ,Name = "SD"},

new Supplier{City = "CC" ,Name = "SE"}

};


数据上的关联

必须用equals关键字,不能用“==”比较

var query = from c in Customers

join s in Suppliers

on c.Cityequalss.City

select new { CCity =c.City, CName = c.Name,SCity= s.City,SName =s.Name };

foreach(var item in query){

Console.WriteLine(item.ToString());

}


数据上的关联

运行结果:

{ CCity = CA, CName = CustA, SCity = CA, SName = SA }

{ CCity = CB, CName = CustB, SCity = CB, SName = SB }

{ CCity = CC, CName = CustC, SCity = CC, SName = SC }

{ CCity = CC, CName = CustC, SCity = CC, SName = SD }

{ CCity = CC, CName = CustC, SCity = CC, SName = SE }


数据上的关联2

var query = from c in Customers

join s in Suppliers

on c.City equals s.City

into customerSuppliers

select new { CCity = c.City, CName = c.Name, customerSuppliers };

foreach(var item in query){

Console.WriteLine(string.Format("CCity = {0}, CName = {1},", item.CCity, item.CName));

foreach (var sup in item.customerSuppliers){

Console.WriteLine(string.Format("\t->SCity = {0},SName = {1}",sup.City,sup.Name));}}


数据上的关联2

CCity = CA, CName = CustA,

->SCity = CA,SName = SA

CCity = CB, CName = CustB,

->SCity = CB,SName = SB

CCity = CC, CName = CustC,

->SCity = CC,SName = SC

->SCity = CC,SName = SD

->SCity = CC,SName = SE

CCity = CD, CName = CustD,


数据上的关联3

from c in categories  

join p in products   

    on new { c.IdCategory, c.Year } equals new { p.IdCategory, p.Year } 

    into productsByCategory


Take

int[] numbers = { 10, 9, 8, 7, 6 };

numbers.Take (3)


Skip

int[] numbers = { 10, 9, 8, 7, 6 };

numbers.Skip (3)


Reverse
Reverse

int[] numbers = { 10, 9, 8, 7, 6 };

numbers.Reverse()


First last
First,Last

int[] numbers = { 10, 9, 8, 7, 6 };

numbers.First();

运行结果:

numbers.Last();

运行结果:


Count
Count

int[] numbers = { 10, 9, 8, 7, 6 };

numbers.Count()


Min

int[] numbers = { 10, 9, 8, 7, 6 };

numbers.Min()


Any

int[] numbers = { 10, 9, 8, 7, 6 };

numbers.Any();//如果有元素即为true,否则为false

numbers.Any (n => n % 2 == 1);


Contains
Contains

int[] numbers = { 10, 9, 8, 7, 6 };

numbers.Contains (9);


Contains1
Contains

  • 需要覆盖GetHashCode和Equals方法

  • 改Order类为值类型

  • public static bool Contains<TSource>(

  • this IEnumerable<TSource> source,

  • TSource value,

  • IEqualityComparer<TSource> comparer )

var orderOfProductOne = new Order {IdOrder = 1, Quantity = 3, IdProduct =   

    1 , Shipped = false, Month = "January"};  

bool result = Orders.Contains(orderOfProductOne);


Concat
Concat

int[] seq1 = { 1, 2, 3 };

int[] seq2 = { 3, 4, 5 };

seq1.Concat (seq2)


Union
Union

int[] seq1 = { 1, 2, 3 };

int[] seq2 = { 3, 4, 5 };

seq1.Union (seq2)


Distinct
Distinct

string[] names = { "Tom","Tom", "Dick", "Harry", "Mary", "Jay" , "Jay"};

IEnumerable<string> query = names.Distinct();


Group by
 group by

Developer[] developers = new Developer[] { 

    new Developer { Name = "Paolo", Language = "C#" },  

    new Developer { Name = "Marco", Language = "C#" },  

    new Developer { Name = "Frank", Language = "VB.NET" },  

};  

vardevelopersGroupedByLanguage =  

    from  d in developers  

 group d by d.Language;  

foreach (var group  in developersGroupedByLanguage) { 

Console.WriteLine("Language: {0}", group.Key); 

foreach (var item in group) { 

Console.WriteLine("\t{0}", item.Name);  

    }  

}


Group by1
group by

Language: C# 

        Paolo  

        Marco  

Language: VB.NET  

        Frank


Group by 2
group by 2

Developer[] developers = new Developer[] { 

    new Developer { Name = "Paolo", Language = "C#", Age = 32 },  

    new Developer { Name = "Marco", Language = "C#", Age = 37},  

    new Developer { Name = "Frank", Language = "VB.NET", Age = 48  },  

};  

vardevelopersGroupedByLanguage = 

    from  d in developers  

    group d by new { d.Language, AgeCluster = (d.Age / 10) * 10 };

foreach (var group in developersGroupedByLanguage) {  

Console.WriteLine("Language: {0}", group.Key);  

foreach (var item in group) {  

Console.WriteLine("\t{0}", item.Name);  

    }  }


Group by 21
group by 2

Language: { Language = C#, AgeCluster = 30 }

        Paolo  

        Marco  

Language: { Language = VB.NET, AgeCluster = 40 }  

        Frank


Group by 3
group by 3

vardevelopersGroupedByLanguage = 

    from   d in developers  

    group  d by d.Languageinto developersGrouped

    select new {  

        Language = developersGrouped.Key,  

DevelopersCount = developersGrouped.Count()

    };  

foreach (var group in developersGroupedByLanguage) {  

Console.WriteLine ("Language {0} contains {1} developers",  

group.Language, group.DevelopersCount);  

}


Oftype
OfType

运行结果:

Mango

Orange

Apple

Banana

System.Collections.ArrayList fruits = new System.Collections.ArrayList(4);

fruits.Add("Mango");

fruits.Add("Orange");

fruits.Add("Apple");

fruits.Add(3.0);

fruits.Add("Banana");

IEnumerable<string> query1 = fruits.OfType<string>();

foreach (string fruit in query1) { Console.WriteLine(fruit); }


Cast

运行结果:

Apple

mango

System.Collections.ArrayList fruits = new System.Collections.ArrayList();

fruits.Add("apple");

fruits.Add("mango");

IEnumerable<string> query = fruits.Cast<string>().Select(fruit => fruit);

foreach (string fruit in query) { Console.WriteLine(fruit); }


Oftype vs cast
OfTypevs Cast

  • OfType: filters the source sequence, yielding only items of type TResult. It is useful in the case of sequences with items of different types.

  • Cast: enumerates the source sequence and tries to yield each item, cast to type TResult. In the case of failure, an InvalidCastException error will be thrown.


Deferred query evaluation
Deferred Query Evaluation

var numbers = new List<int>();

numbers.Add(1);

IEnumerable<int> query = numbers.Select(n => n * 10);

numbers.Add(2);

foreach(var a in query){

Console.WriteLine(a);}


Deferred query evaluation1
Deferred Query Evaluation

static Boolean DoSomething(Developer dev) { 

    if (dev.Age > 40)  

        throw new ArgumentOutOfRangeException("dev");    

    return (dev.Language == "C#");  

}  


Deferred query evaluation2
Deferred Query Evaluation

Developer[] developers = new Developer[] { 

    new Developer { Name = "Frank", Language = "VB.NET", Age = 48  },  … …

};

var query =  

    from   d in developers  

    let    SomethingResult = DoSomething(d)  

    select new { d.Name, SomethingResult };  

try { 

foreach (var item in query) {  

Console.WriteLine(item);  

    } 

}  

catch (ArgumentOutOfRangeException e) {  

Console.WriteLine(e.Message);  


总结

  • Contains

  • Concat

  • Union

  • Distinct

  • group by

  • OfType

  • Cast

  • Deferred Query Evaluation

  • 数据结构上的关联

  • 数据上的关联

  • OrderBy

  • Take

  • Skip

  • Reverse

  • First,Last

  • Count

  • Min

  • Any


ad