一、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);
}
{
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);
}
}
{
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();
}
{
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;
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);
}
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);
}
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;
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;
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);
}
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());
}
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;
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;
// 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;
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.
}
{
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;
}
}
{
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!
}
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();
}
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.
}
foreach ( object o in objs)
{
Console.WriteLine(o); // Calls ToString() on each anonymous object.
}
注意:
1、不能给 ToArray<T>()指定类型,因为这里是隐式类型,到编译时才可用。
2、不能使用System.Array 的定义语法,只能使用该对象,同样因为隐式类型。
3、当需要使用投影的查询结果集时,把其转换为Array类型是必须的,当然这样会丢失强类型的好处。