戈多

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
一、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类型是必须的,当然这样会丢失强类型的好处。
posted on 2008-07-13 23:23  戈多  阅读(2044)  评论(0编辑  收藏  举报