C# 2008 学习笔记 - LINQ基础(三)- LINQ语法

一、LINQ查询符列表

Query Operators

Meaning in Life

from, in

Used to define the backbone for any LINQ expression, which allows you to extract a subset of data from a fitting container.

where

Used to define a restriction for which items to extract from a container.

select

Used to select a sequence from the container.

join, on, equals, into

Performs joins based on specified key. Remember, these “joins” do not need to have anything to do with data in a relational database.

orderby, ascending, descending

Allows the resulting subset to be ordered in ascending or descending order.

group, by

Yields a subset with data grouped by a specified value.


另外还有一些没有操作符号,而是以扩展函数(泛型函数)的方式提供的函数:

用不同方式产生结果集:  Reverse<>(), ToArray<>(), ToList<>() 

集合操作:  Distinct<>(), Union<>(), Intersect<>()

统计函数: Count<>(), Sum<>(), Min<>(), Max<>()

二、使用Enumerable获取Counts

为了使用这些Enumerable扩展函数,一般把LINQ查询表达式用括号括起来,先转换为IEnumerable<T>兼容的对象。

static   void  GetCount()
{
string [] currentVideoGames  =  { " Morrowind " ,  " BioShock " ,
" Half Life 2: Episode 1 " ,  " The Darkness " ,
" Daxter " ,  " System Shock 2 " };
//  Get count from the query.
int  numb  =  (from g  in  currentVideoGames
where  g.Length  >   6
orderby g
select g).Count < string > ();
//  numb is the value 5.
Console.WriteLine( " {0} items honor the LINQ query. " , numb);
}

三、定义演示的实例

class  Car
{
public   string  PetName  =   string .Empty;
public   string  Color  =   string .Empty;
public   int  Speed;
public   string  Make  =   string .Empty;
public   override   string  ToString()
{
return   string .Format( " Make={0}, Color={1}, Speed={2}, PetName={3} " ,
Make, Color, Speed, PetName);
}
}

static   void  Main( string [] args)
{
Console.WriteLine( " ***** Fun with Query Expressions *****/n " );
//  This array will be the basis of our testing
Car[] myCars  =   new  [] {
new  Car{ PetName  =   " Henry " , Color  =   " Silver " , Speed  =   100 , Make  =   " BMW " },
new  Car{ PetName  =   " Daisy " , Color  =   " Tan " , Speed  =   90 , Make  =   " BMW " },
new  Car{ PetName  =   " Mary " , Color  =   " Black " , Speed  =   55 , Make  =   " VW " },
new  Car{ PetName  =   " Clunker " , Color  =   " Rust " , Speed  =   5 , Make  =   " Yugo " },

new  Car{ PetName  =   " Hank " , Color  =   " Tan " , Speed  =   0 , Make  =   " Ford " },
new  Car{ PetName  =   " Sven " , Color  =   " White " , Speed  =   90 , Make  =   " Ford " },
new  Car{ PetName  =   " Mary " , Color  =   " Black " , Speed  =   55 , Make  =   " VW " },
new  Car{ PetName  =   " Zippy " , Color  =   " Yellow " , Speed  =   55 , Make  =   " VW " },
new  Car{ PetName  =   " Melvin " , Color  =   " White " , Speed  =   43 , Make  =   " Ford " }
};
//  We will call various methods here!
Console.ReadLine();
}

四、LINQ语法

基本语法
var result =  from item 
                  in container 
                  orderby value ascending/descending 
                  select item;


1、获取全部记录
var allCars  =  from c  in  myCars select c;


2、只获取字段名称
var names  =  from c  in  myCars select c.PetName;
这里names就是隐式类型的变量。


3、使用 Enumerable.Distinct<T>()
var makes  =  (from c  in  myCars select c.Make).Distinct < string > ();



4、即可以在定义的时候调用Enumberalbe扩展函数
var names  =  from c  in  myCars select c.PetName;
foreach  (var n  in  names)
{
Console.WriteLine( " Name: {0} " , n);
}

也可以在兼容的数组类型上调用
var makes  =  from c  in  myCars select c.Make;
Console.WriteLine( " Distinct makes: " );
foreach  (var m  in  makes.Distinct < string > ())
{
Console.WriteLine( " Make: {0} " , m);
}

//  Now get only the BMWs.
var onlyBMWs  =  from c  in  myCars  where  c.Make  ==   " BMW "  select c;

//  Get BMWs going at least 100 mph.
var onlyFastBMWs  =  from c  in  myCars
where  c.Make  ==   " BMW "   &&  c.Speed  >=   100
select c;

5、生成新的数据类型(投影)
var makesColors  =  from c  in  myCars select  new  {c.Make, c.Color};

6、Reverse<T>()
var subset  =  (from c  in  myCars select c).Reverse < Car > ();
foreach (Car c in subset)
{
Console.WriteLine("{0} is going {1} MPH", c.PetName, c.Speed);
}

或者
var subset  =  from c  in  myCars select c;
foreach  (Car c  in  subset.Reverse < Car > ())
{
Console.WriteLine(c.ToString());
}

7、排序
默认是 ascending
//  Order all the cars by PetName.
var subset  =  from c  in  myCars orderby c.PetName select c;

//  Now find the cars that are going less than 55 mph,
//  and order by descending PetName
subset  =  from c  in  myCars
where  c.Speed  >   55  orderby c.PetName descending select c;

默认顺序时也可以明确指明
var subset  =  from c  in  myCars
orderby c.PetName ascending select c;

8、 Enumerable.Except()

两个 IEnumerable<T>兼容的对象的差集

static   void  GetDiff()
{
List < string >  myCars  =   new  List < String >
{  " Yugo " ,  " Aztec " ,  " BMW " };
List < string >  yourCars  =   new  List < String >
{  " BMW " ,  " Saab " ,  " Aztec "  };
var carDiff  = (from c  in  myCars select c)
.Except(from c2  in  yourCars select c2);
Console.WriteLine( " Here is what you don't have, but I do: " );
foreach  ( string  s  in  carDiff)
Console.WriteLine(s);  //  Prints Yugo.
}

五、使用LINQ查询结果

如果查询结果是强类型的,如string[],List<T>等,就可以不用var类型,而是使用合适的 IEnumerable<T>IEnumerable(因为IEnumerable<T>也扩展了IEnumerable)类型。
class  Program
{
static   void  Main( string [] args)
{
Console.WriteLine( " ***** LINQ Transformations *****/n " );
IEnumerable < string >  subset  =  GetStringSubset();
foreach  ( string  item  in  subset)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
static  IEnumerable < string >  GetStringSubset()
{
string [] currentVideoGames  =  { " Morrowind " ,  " BioShock " ,
" Half Life 2: Episode 1 " ,  " The Darkness " ,
" Daxter " ,  " System Shock 2 " };
//  Note subset is an IEnumerable<string> compatible object.
IEnumerable < string >  subset  =  from g  in  currentVideoGames
where  g.Length  >   6
orderby g
select g;
return  subset;
}
}


只有该函数原型返回类型是 IEnumerable<string>,才可以使用var定义返回结果集类型。

但是在投影操作中,由于结果集合类型是隐式的,在编译时才能确定,所以这里强制规定必须使用var
//  Error! Can't return a var data type!
static  var GetProjectedSubset()
{
Car[] myCars  =   new  Car[] {
new  Car{ PetName  =   " Henry " , Color  =   " Silver " , Speed  =   100 , Make  =   " BMW " },
new  Car{ PetName  =   " Daisy " , Color  =   " Tan " , Speed  =   90 , Make  =   " BMW " },
new  Car{ PetName  =   " Mary " , Color  =   " Black " , Speed  =   55 , Make  =   " VW " },
new  Car{ PetName  =   " Clunker " , Color  =   " Rust " , Speed  =   5 , Make  =   " Yugo " },
new  Car{ PetName  =   " Melvin " , Color  =   " White " , Speed  =   43 , Make  =   " Ford " }
};

var makesColors  =  from c  in  myCars select  new  { c.Make, c.Color };
return  makesColors;  //  Nope!
}

可以使用 ToArray<T>()把投影结果集转化为标志的CRL数组对象:
//  Return value is now an Array.
static  Array GetProjectedSubset()
{
Car[] myCars  =   new  Car[]{
new  Car{ PetName  =   " Henry " , Color  =   " Silver " , Speed  =   100 , Make  =   " BMW " },
new  Car{ PetName  =   " Daisy " , Color  =   " Tan " , Speed  =   90 , Make  =   " BMW " },
new  Car{ PetName  =   " Mary " , Color  =   " Black " , Speed  =   55 , Make  =   " VW " },
new  Car{ PetName  =   " Clunker " , Color  =   " Rust " , Speed  =   5 , Make  =   " Yugo " },
new  Car{ PetName  =   " Melvin " , Color  =   " White " , Speed  =   43 , Make  =   " Ford " }
};
var makesColors  =  from c  in  myCars select  new  { c.Make, c.Color };
//  Map set of anonymous objects to an Array object.
//  Here were are relying on type inference of the generic
//  type parameter, as we don't know the type of type!
return  makesColors.ToArray();
}

然后,就可以这样使用:
Array objs  =  GetProjectedSubset();
foreach  ( object  o  in  objs)
{
Console.WriteLine(o);  //  Calls ToString() on each anonymous object.
}

注意:

1、不能给 ToArray<T>()指定类型,因为这里是隐式类型,到编译时才可用。
2、不能使用System.Array 的定义语法,只能使用该对象,同样因为隐式类型。
3、当需要使用投影的查询结果集时,把其转换为Array类型是必须的,当然这样会丢失强类型的好处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值