一、投影操作符

1. Select

Select操作符对单个序列或集合中的值进行投影。下面的示例中使用select从序列中返回Employee表的所有列:

using (NorthwindDataContext db=new NorthwindDataContext())

{

//查询语法

var query =

from e in db.Employees

where e.FirstName.StartsWith("M")

select e;

//方法语法

var q =

db.Employees

.Where(e => e.FirstName.StartsWith("M"))

.Select(e => e);

foreach (var item in query)

{

Console.WriteLine(item.FirstName);

}

}

当然,你也可以返回单个列,例如:

var query =

from e in db.Employees

where e.FirstName.StartsWith("M")

select e.FirstName;

你也可以返回序列中的某几列,例如:

var query =

from e in db.Employees

where e.FirstName.StartsWith("M")

select new

{

e.FirstName,

e.LastName,

e.Title

};

2. SelectMany

SelectMany操作符提供了将多个from子句组合起来的功能,它将每个对象的结果合并成单个序列。下面是一个示例:

using (NorthwindDataContext db=new NorthwindDataContext())

{

//查询语法

var query =

from e in db.Employees

from o in e.Orders

select o;

//方法语法

var q =

db.Employees

.SelectMany(e => e.Orders);

foreach (var item in query)

{

Console.WriteLine(item.Freight);

}

}

二、限制操作符

Where是限制操作符,它将过滤标准应用在序列上,按照提供的逻辑对序列中的数据进行过滤。

Where操作符不启动查询的执行。当开始对序列进行遍历时查询才开始执行,此时过滤条件将被应用到查询中。Where操作符的使用方法已经在第一节中出现过,这里不再冗述。

三、排序操作符

排序操作符,包括OrderBy、OrderByDescending、ThenBy、ThenByDescending和Reverse,提供了升序或者降序排序。

1. OrderBy

OrderBy操作符将序列中的元素按照升序排列。下面的示例演示了这一点:

using (NorthwindDataContext db = new NorthwindDataContext())

{

//查询语法

var query =

from e in db.Employees

orderby e.FirstName

select e;

//方法语法

var q =

db.Employees

.OrderBy(e => e.FirstName)

.Select(e => e);

foreach (var item in q)

{

Console.WriteLine(item.FirstName);

}

}

这里可以使用OrderBy的重载方法OrderBy(Func<T,TKey>,IComparer<Tkey>)来指定序列的排序方式。

2. OrderByDescending

OrderByDescending操作符将序列中的元素按照降序排列。用法与OrderBy相同,这里不再演示。

3. ThenBy

ThenBy操作符实现按照次关键字对序列进行升序排列。此操作符的查询语法与方法语法略有不同,以下代码演示了这一点:

using (NorthwindDataContext db = new NorthwindDataContext())

{

//查询语法

var query =

from e in db.Employees

orderby e.FirstName,e.LastName

select e;

//方法语法

var q =

db.Employees

.OrderBy(e => e.FirstName)

.ThenBy(e => e.LastName)

.Select(e => e);

foreach (var item in query)

{

Console.WriteLine(item.FirstName);

}

}

4. ThenByDescending

ThenByDescending操作符实现按照次关键字对序列进行降序排列。此操作符的查询语法与方法语法略有不同,以下代码演示了这一点:

using (NorthwindDataContext db = new NorthwindDataContext())

{

//查询语法

var query =

from e in db.Employees

orderby e.FirstName,e.LastName descending

select e;

//方法语法

var q =

db.Employees

.OrderBy(e => e.FirstName)

.ThenByDescending(e => e.LastName)

.Select(e => e);

foreach (var item in query)

{

Console.WriteLine(item.FirstName);

}

}

5. Reverse

Reverse将会把序列中的元素按照从后到前的循序反转。需要注意的是,Reverse方法的返回值是void,以下代码演示了这一点:

using (NorthwindDataContext db = new NorthwindDataContext())

{

//方法语法

var q =

db.Employees

.Select(e => e.FirstName)

.ToList();

q.Reverse();

foreach (var item in q)

{

Console.WriteLine(item);

}

}

四、联接操作符

联接是指将一个数据源对象与另一个数据源对象进行关联或者联合的操作。这两个数据源对象通过一个共同的值或者属性进行关联。

LINQ有两个联接操作符:Join和GroupJoin。

1. Join

Join操作符类似于T-SQL中的inner join,它将两个数据源相联接,根据两个数据源中相等的值进行匹配。例如,可以将产品表与产品类别表相联接,得到产品名称和与其相对应的类别名称。以下的代码演示了这一点:

using (NorthwindDataContext db = new NorthwindDataContext())

{

db.Log = Console.Out; //将生成的T-SQL语句输出到控制台中

//查询语法

var query =

from p in db.Products

join c in db.Categories on p.CategoryID equals c.CategoryID

where p.CategoryID == 1

select p;

//方法语法

var q =

db.Products

.Join

(

db.Categories,

p => p.CategoryID,

c => c.CategoryID,

(p, c) => p

)

.Where(p => p.CategoryID == 1);

foreach (var item in query)

{

Console.WriteLine(item.ProductName);

}

}

以上代码为表述清晰加入了一个条件“where p.CategoryID == 1”,即仅返回产品类别ID为1的所有产品。

2. GroupJoin

GroupJoin操作符常应用于返回“主键对象-外键对象集合”形式的查询,例如“产品类别-此类别下的所有产品”。以下的代码演示了这一点:

using (NorthwindDataContext db = new NorthwindDataContext())

{

db.Log = Console.Out; //将生成的T-SQL语句输出到控制台中

//查询语法

var query =

from c in db.Categories

join p in db.Products on c.CategoryID equals p.CategoryID into r

select new

{

c.CategoryName,

Products = r

};

//方法语法

var q =

db.Categories

.GroupJoin

(

db.Products,

c => c.CategoryID,

p => p.CategoryID,

(c, p) => new

{

c.CategoryName,

Products = p

}

);

foreach (var item in query)

{

Console.WriteLine("{0} =>", item.CategoryName);

foreach (var p in item.Products)

{

Console.WriteLine(p.ProductName);

}

Console.WriteLine("----------------------------------------------");

}

}

五、分组操作符

分组是根据一个特定的值将序列中的元素进行分组。LINQ只包含一个分组操作符:GroupBy

下面的示例中使用了产品表,以CategoryID作为分组关键值,按照产品类别对产品进行了分组。

using (NorthwindDataContext db = new NorthwindDataContext())

{

db.Log = Console.Out; //将生成的T-SQL语句输出到控制台中

//查询语法

var query =

from p in db.Products

group p by p.CategoryID;

//方法语法

var q =

db.Products

.GroupBy(p => p.CategoryID);

foreach (var item in query)

{

Console.WriteLine("{0} =>", item.Key);

foreach (var p in item)

{

Console.WriteLine(p.ProductName);

}

Console.WriteLine("----------------------------------------------");

}

}

执行GroupBy得到的序列中包含的元素类型为IGrouping<TKey?, T>,其Key属性代表了分组时使用的关键值,遍历IGrouping<TKey?, T>元素可以读取到每一个T类型。在此示例中,对应的元素类型为IGrouping<int?, Products>,其Key属性即为类别ID,遍历它可以读取到每一个产品对象。

六、串联操作符

串联是一个将两个集合联接在一起的过程。在LINQ中,这个过程通过Concat操作符来实现。

在下面的示例中,将会把类别名称串联在产品名称之后:

using (NorthwindDataContext db = new NorthwindDataContext())

{

db.Log = Console.Out; //将生成的T-SQL语句输出到控制台中

//方法语法

var q =

db.Products

.Select(p => p.ProductName)

.Concat

(

db.Categories.Select(c => c.CategoryName)

);

foreach (var item in q)

{

Console.WriteLine(item);

}

}

七、聚合操作符

聚合函数将在序列上执行特定的计算,并返回单个值,如计算给定序列平均值、最大值等。共有7种LINQ聚合查询操作符:Aggregate、Average、Count、LongCount、Max、Min和Sum。

1. Aggregate

Aggregate操作符对集合值执行自定义聚合运算。例如,需要列出所有产品类别清单,每个类别名称之间用顿号连接。以下的代码演示了这一过程:

using (NorthwindDataContext db = new NorthwindDataContext())

{

db.Log = Console.Out; //将生成的T-SQL语句输出到控制台中

//方法语法

var q =

db.Categories

.Select(c => c.CategoryName)

.ToArray()

.Aggregate((current, next) => String.Format("{0}、{1}", current, next));

Console.WriteLine(q);

}

如果你对这一过程有些迷惑,那么请参照以下代码:

var query =

db.Categories

.Select(c => c.CategoryName)

.ToArray();

string r = String.Empty;

foreach (var item in query)

{

r += "、";

r += item;

}

r = r.Substring(1); //去除第一个顿号

Console.WriteLine(r);

2. Average

求集合中元素的平均值,返回值类型double

3. Count

求集合中元素的个数,返回值类型Int32

4. LongCount

求集合中元素的个数,返回值类型Int64

5. Max

求集合中元素的最大值

6. Min

求集合中元素的最小值

7. Sum

求集合中元素的和

八、集合操作符

LINQ 中的集合操作符是指根据相同或不同集合(或集)中是否存在等效元素来生成结果集的查询操作,一共有4种:

方法名

说明

Distinct

从集合移除重复值。

 

Except

返回差集,差集是指位于一个集合但不位于另一个集合的元素。

 

Intersect

返回交集,交集是指同时出现在两个集合中的元素。

 

Union

返回并集,并集是指位于两个集合中任一集合的唯一的元素。

 

使用方式均为“集合1.方法名(集合2)”,返回值为运算结果的集合,这里就不演示了。

九、生成操作符

生成是指创建新的值序列。

1. Empty

Empty操作符返回一个指定类型的空集合。这里的空不是null,而是元素数量为0的集合。以下的示例演示了如何创建一个IEnumerable<int>类型的空集合:

var q = Enumerable.Empty<int>();

Console.WriteLine(q == null);

Console.WriteLine(q.Count());

2. DefaultIfEmpty

DefaultIfEmpty将空集合替换为具有默认值的单一实例集合。执行此方法获得的集合将至少含有一个元素,这是因为DefaultIfEmpty方法需要两个参数,第一个参数是一个泛型集合,第二个参数是相应类型的单个元素,如果第一个参数中不含有任何元素,它将返回第二个参数指定的单个元素。如果你使用了DefaultIfEmpty方法的重载方法DefaultIfEmpty<T>(IEnumerable<T> array),如果指定的array集合为空,那么将返回一个类型为T,值为null的单个对象。以下的代码演示了这一过程:

using (NorthwindDataContext db = new NorthwindDataContext())

{

db.Log = Console.Out; //将生成的T-SQL语句输出到控制台中

//方法语法

var q =

Enumerable.DefaultIfEmpty

(

db.Employees

.Where(e => e.FirstName.StartsWith("Aaf")) //更改此处的条件可获得不同的集合

, new Employees() { FirstName = "Sunny D.D" }

);

Console.WriteLine(q.Count());

foreach (var item in q)

{

Console.WriteLine(item.FirstName);

}

}

3. Range

Range操作符用于生成指定范围内的整数的序列。它需要两个参数,第一个参数是序列开始的整数值,第二个参数是序列中整数的数量。下面的示例演示了使用Range操作符来生成从0到9的整数序列:

var q =

Enumerable.Range(0, 10);

foreach (var item in q)

{

Console.WriteLine(item);

}

4. Repeat

Repeat操作符用于生成包含一个重复值的集合。它需要两个参数,第一个参数是任意类型的元素,第二个参数是生成的序列中所包含此元素的数量。下面的示例演示了使用Repeat来生成一个包含10个0的序列:

var q =

Enumerable.Repeat(0, 10);

foreach (var item in q)

{

Console.WriteLine(item);

}

十、转换操作符

转换操作符是用来实现将输入对象的类型转变为序列的功能。名称以“As”开头的转换方法可更改源集合的静态类型但不枚举(延迟加载)此源集合。名称以“To”开头的方法可枚举(即时加载)源集合并将项放入相应的集合类型。

1. AsEnumerable

所有实现了IEnumerable<T>接口的类型都可以调用此方法来获取一个IEnumerable<T>集合。此方法一般仅用于实现类中的方法与IEnumerable<T>接口方法重名时。例如,实现类Test中有一个Where方法,当使用Test对象调用Where时,将执行Test自身的Where方法过程。如果要执行IEnumerable<T>的Where方法,便可以使用AsEnumerable进行进行转换后,再调用Where方法即可。当然,将实现类Test隐式转换为IEnumerable<T>接口,再调用接口的Where方法也能达到同样的效果。以下的代码演示了这一过程:

class AsEnumerableTest<T> : List<T>

{

public void Where(Func<T, bool> func)

{

Console.WriteLine("AsEnumerableTest的Where方法");

}

}

public static void AsEnumerable()

{

AsEnumerableTest<int> q = new AsEnumerableTest<int>() { 1,2,3,4 };

q.Where(r => r < 3);

//q.AsEnumerable().Where(r => r < 3);

//IEnumerable<int> i = q;

//i.Where(r => r < 3);

}

2. Cast

Cast<T> 方法通过提供必要的类型信息,可在IEnumerable(非泛型)的派生对象上调用Cast<T> 方法来获得一个IEnumerable<T>对象。例如,ArrayList 并不实现IEnumerable<T>,但通过调用 ArrayList 对象上的 Cast<T>(),就可以使用标准查询运算符查询该序列。

如果集合中的元素无法强制转换为 T 类型,则此方法将引发异常。以下代码演示了这一过程:

ArrayList array = new ArrayList();

array.Add("Bob");

array.Add("Jack");

array.Add(1);

foreach (var item in array.Cast<string>())

{

Console.WriteLine(item);

}

运行此代码,可以输出“Bob”、“Jack”,然后会报出一个异常“无法将int强制转换为string”,这说明Cast方法也是延迟执行实现的,只有在枚举过程中才将对象逐个强制转换为T类型。

3. OfType

OfType <T> 方法通过提供必要的类型信息,可在IEnumerable(非泛型)的派生对象上调用OfType <T> 方法来获得一个IEnumerable<T>对象。执行OfType<T>方法将返回集合中强制转换类型成功的所有元素。也就是说,OfType<T>方法与Cast<T> 方法的区别在于,如果集合中的元素在强制转换失败的时候会跳过,而不是抛出异常。

4. ToArray

ToArray 操作符可以在IEnumerable<T> 类型的任何派生对象上调用,返回值为T类型的数组。

5. ToDictionary

ToDictionary操作符根据指定的键选择器函数,从IEnumerable<T>创建一个Dictionary<TKey, TValue>。下面的示例中,将查询到的产品类别集合转换为Dictionary<类别ID,类别名称>的键-值集合:

using (NorthwindDataContext db = new NorthwindDataContext())

{

db.Log = Console.Out; //将生成的T-SQL语句输出到控制台中

//方法语法

var q =

db.Categories

.ToDictionary

(

c => c.CategoryID,

c => c.CategoryName

);

foreach (var item in q)

{

Console.WriteLine("{0} - {1}",item.Key,item.Value);

}

}

需要注意的是,如果省略ToDictionary方法的第二个参数(值选择函数),那么Value将会保存一个类别对象。还有,如果Key为null,或者出现重复的Key,都将导致抛出异常。

6. ToList

ToList操作符可以在IEnumerable<T> 类型的任何派生对象上调用,返回值为List<T>类型的对象。

7. ToLookup

ToLookup操作符将创建一个 Lookup<TKey, TElement>对象,这是一个one-to-many集合,一个Key可以对应多个Value。以下的示例以产品表的所有数据作为数据源,以类别ID作为Key调用了ToLookup方法,然后遍历返回的Lookup<TKey, TElement>对象,输出了类别ID以及此类别下的所有产品名称:

using (NorthwindDataContext db = new NorthwindDataContext())

{

db.Log = Console.Out; //将生成的T-SQL语句输出到控制台中

//方法语法

var q =

db.Products

.ToLookup

(

p => p.CategoryID,

p => p.ProductName

);

foreach (var item in q)

{

Console.WriteLine(item.Key);

foreach (var p in item)

{

Console.WriteLine(p);

}

}

}

可以看出,ToLookup操作与GroupBy操作很相似,只不过GroupBy是延迟加载的,而ToLookup是即使加载。

十一、元素操作符

元素操作符将从一个序列中返回单个指定的元素。

1. First

First操作将返回序列中的第一个元素。如果序列中不包含任何元素,则First<T>方法将引发异常。若要在源序列为空时返回默认值,需要使用FirstOrDefault方法。以下代码演示了First<T>方法的使用方式:

using (NorthwindDataContext db = new NorthwindDataContext())

{

db.Log = Console.Out; //将生成的T-SQL语句输出到控制台中

//无参

var query =

db.Employees

.First();

//有参

var q =

db.Employees

.First(e => e.FirstName.StartsWith("S"));

Console.WriteLine(q.FirstName);

}

上述代码中使用了First<T>方法的无参方式与有参方式。First<T>的有参方式中可以指定一个条件,操作将返回序列中满足此条件的第一个元素。从查询结果上看,source.First<T>(条件)方法与source.Where(条件).First<T>()是一样的,但是需要注意“First<T>(条件)操作将返回序列中满足此条件的第一个元素”,这将忽略后面的遍历操作,效率更高。

2. FirstOrDefault

FirstOrDefault方法将返回序列中的第一个元素;如果序列中不包含任何元素,则返回默认值。它也可以像First方法一样传递一个条件。需要说明的是如果序列中不包含任何元素,返回的默认值是个怎样的元素。在这之前,先来看一下FirstOrDefault方法是如何实现的:

public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)

{

if (source == null)

{

throw Error.ArgumentNull("source");

}

IList<TSource> list = source as IList<TSource>;

if (list != null)

{

if (list.Count > 0)

{

return list[0];

}

}

else

{

using (IEnumerator<TSource> enumerator = source.GetEnumerator())

{

if (enumerator.MoveNext())

{

return enumerator.Current;

}

}

}

return default(TSource);

}

  1. 如果调用FirstOrDefault方法的序列为空,抛出异常
  2. 如果序列成功转换为List<T>,并且元素数量大于0,则返回首个元素
  3. 如果序列没有成功转换为List<T>,则尝试获取序列的遍历器,然后再调用遍历器的MoveNext方法,如果返回值为true,则返回当前的元素。
  4. 如果上述操作都没有执行,则使用default(T)关键字返回类型T的默认值

以下给出MSDN中,对于default(T)关键字的描述:

在泛型类和泛型方法中产生的一个问题是,在预先未知以下情况时,如何将默认值分配给参数化类型 T:

  • T 是引用类型还是值类型。
  • 如果 T 为值类型,则它是数值还是结构。

给定参数化类型 T 的一个变量 t,只有当 T 为引用类型时,语句 t = null 才有效;只有当 T 为数值类型而不是结构时,语句 t = 0 才能正常使用。解决方案是使用 default 关键字,此关键字对于引用类型会返回 null,对于数值类型会返回零。对于结构,此关键字将返回初始化为零或 null 的每个结构成员,具体取决于这些结构是值类型还是引用类型。

3. Last

Last方法将返回序列中的最后一个元素。使用方法参照First。

4. LastOrDefault

LastOrDefault方法将返回序列中的最后一个元素;如果序列中不包含任何元素,则返回默认值。使用方法参照FirstOrDefault。

5. ElementAt

ElementAt方法返回序列中指定索引处的元素。使用方法参照First。需要注意的是如果索引超出范围会导致异常。

6. ElementAtOrDefault

ElementAtOrDefault方法将返回序列中指定索引处的元素;如果索引超出范围,则返回默认值。使用方法参照FirstOrDefault。

7. Single

Single方法的无参形式将从一个序列中返回单个元素,如果该序列包含多个元素,或者没有元素数为0,则会引发异常。也就是说,在序列执行Single方法的无参形式时,必须保证该序列有且仅有一个元素。

Single方法的有参形式将从一个序列中返回符合指定条件的唯一元素,如果有多个元素,或者没有元素符合这一条件,则会引发异常。以下代码演示了Single的使用方式:

using (NorthwindDataContext db = new NorthwindDataContext())

{

db.Log = Console.Out; //将生成的T-SQL语句输出到控制台中

//方法语法

var q =

db.Employees

.Single();

var query =

db.Employees

.Single(e => e.FirstName.StartsWith("S"));

Console.WriteLine(query.FirstName);

}

8. SingleOrDefault

SingleOrDefault方法的无参形式将从一个序列中返回单个元素。如果元素数为0,则返回默认值。如果该序列包含多个元素,则会引发异常。

SingleOrDefault方法的有参形式将从一个序列中返回符合指定条件的唯一元素,如果元素数为0,则返回默认值;如果该序列包含多个元素,则会引发异常。SingleOrDefault的使用方式与Single相同。

需要注意的是,Single方法与SingleOrDefault方法都是即时加载的,在代码进行到方法所在位置时,如果引发了异常,会立刻抛出。

十二、相等操作符

如果两个序列的对应元素相等且这两个序列具有相同数量的元素,则视这两个序列相等。

SequenceEqual方法通过并行地枚举两个数据源并比较相应元素来判断两个序列是否相等。如果两个序列完全相等,返回true,否则返回false。以下代码是SequenceEqual方法的实现过程:

public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second,IEqualityComparer<TSource> comparer)

{

if (comparer == null)

{

comparer = EqualityComparer<TSource>.Default;

}

if (first == null)

{

throw Error.ArgumentNull("first");

}

if (second == null)

{

throw Error.ArgumentNull("second");

}

using (IEnumerator<TSource> enumerator = first.GetEnumerator())

{

using (IEnumerator<TSource> enumerator2 = second.GetEnumerator())

{

while (enumerator.MoveNext())

{

if (!enumerator2.MoveNext() || !comparer.Equals(enumerator.Current, enumerator2.Current))

{

return false;

}

}

if (enumerator2.MoveNext())

{

return false;

}

}

}

return true;

}

以上代码的执行过程为:

  1. 如果比较器为null,赋值为默认值EqualityComparer<TSource>.Default。
  2. 如果序列1为null,抛出异常。
  3. 如果序列2为null,抛出异常。
  4. 遍历序列1。在此过程中,如果序列2到达底端则返回false;如果序列1的当前值与序列2的当前值不同,则返回false。
  5. 序列1遍历完成后,如果序列2未到达底端,则返回false。
  6. 如果第2-5步都没有执行,则返回true。

十三、限定操作符

限定符运算返回一个 Boolean 值,该值指示序列中是否有一些元素满足条件或是否所有元素都满足条件。

下图描述了两个不同源序列上的两个不同限定符运算。第一个运算询问是否有一个或多个元素为字符“A”,结果为 true。第二个运算询问是否所有元素都为字符“A”,结果为true

1. All

All方法用来确定是否序列中的所有元素都满足条件。以下代码演示了All的用法:

string[] source1 = new string[] { "A", "B", "C", "D", "E", "F" };

string[] source2 = new string[] { "A", "A", "A", "A", "A", "A" };

Console.WriteLine(source1.All(w => w == "A")); //console will print "False"

Console.WriteLine(source2.All(w => w == "A")); //console will print "True"

2. Any

Any方法的无参方式用来确定序列是否包含任何元素。如果源序列包含元素,则为 true;否则为 false。

Any方法的有参方式用来确定序列中是否有元素满足条件。只要有一个元素符合指定条件即返回true,如果一个符合指定条件的元素都没有则返回false。以下代码演示了Any方法有参方式的用法:

string[] source1 = new string[] { "A", "B", "C", "D", "E", "F" };

string[] source2 = new string[] { "A", "A", "A", "A", "A", "A" };

Console.WriteLine(source1.Any(w => w == "A")); //console will print "True"

Console.WriteLine(source2.Any(w => w == "A")); //console will print "True"

3. Contains

Contains方法用来确定序列是否包含满足指定条件的元素。如果有返回true,否则返回false。以下代码使用默认的String比较器来判断序列中是否含有指定的字符串:

string[] source1 = new string[] { "A", "B", "C", "D", "E", "F" };

Console.WriteLine(source1.Contains("A")); //console will print "True"

Console.WriteLine(source1.Contains("G")); //console will print "False"

如果要对序列中的元素进行自定义比较,需要一个IEqualityComparer<T>接口的实现类作为比较器,用于比较序列中的元素。

十四、分区操作符

LINQ 中的分区指的是在不重新排列元素的情况下,将输入序列划分为两部分,然后返回其中一个部分的操作。

下图显示对一个字符序列执行三个不同的分区操作的结果。第一个操作返回序列中的前三个元素。第二个操作跳过前三个元素,返回剩余的元素。第三个操作跳过序列中的前两个元素,返回接下来的三个元素。

1. Take

Take(int n)方法将从序列的开头返回数量为n的连续元素。以下代码演示了从一个序列中返回其前五个元素:

int[] source = new int[] { 86, 2, 77, 94, 100, 65, 5, 22, 70, 55, 81, 66, 45 };

var q = source.Take(5);

foreach (var item in q)

{

Console.WriteLine(item);

}

上述代码的运行结果为下图所示:

2. TakeWhile

TakeWhile方法执行时将逐个比较序列中的每个元素是否满足指定条件,直到碰到不符合指定的条件的元素时,返回前面所有的元素组成的序列。以下代码演示了这一过程:

int[] source = new int[] { 86, 2, 77, 94, 100, 65, 5, 22, 70, 55, 81, 66, 45 };

var q = source.TakeWhile(i => i < 100);

foreach (var item in q)

{

Console.WriteLine(item);

}

上述代码的运行结果为下图所示:

3. Skip

Skip(int n)方法将跳过序列开头的n个元素,然后返回其余的连续元素。以下代码演示了从一个序列中跳过前五个元素,然后返回其余的元素组成的序列:

int[] source = new int[] { 86, 2, 77, 94, 100, 65, 5, 22, 70, 55, 81, 66, 45 };

var q = source.Skip(5);

foreach (var item in q)

{

Console.WriteLine(item);

}

上述代码的运行结果为下图所示:

4. SkipWhile

SkipWhile方法执行时将逐个比较序列中的每个元素是否满足指定条件,直到碰到不符合指定的条件的元素时,返回其余所有的元素组成的序列。以下代码演示了这一过程:

int[] source = new int[] { 86, 2, 77, 94, 100, 65, 5, 22, 70, 55, 81, 66, 45 };

var q = source.SkipWhile(i => i < 100);

foreach (var item in q)

{

Console.WriteLine(item);

}

上述代码的运行结果为下图所示:

本文总结

本文介绍了LINQ标准查询操作符。没有这些操作符,LINQ就不会存在。本文为理解这些操作符的功能提供了很好的基础。了解它们将会很有帮助,因为LINQ的各种Provider都是基于这些操作符来完成各自丰富的功能。

 
 
分类: LINQ

LINQ查询操作符 LINQ学习第二篇的更多相关文章

  1. LINQ查询操作符 LINQ学习第二篇[转]

    一.投影操作符 1. Select Select操作符对单个序列或集合中的值进行投影.下面的示例中使用select从序列中返回Employee表的所有列: using (NorthwindDataCo ...

  2. .NET 3.5(5) - LINQ查询操作符之Select、Where、OrderBy、OrderByDescending

    .NET 3.5(5) - LINQ查询操作符之Select.Where.OrderBy.OrderByDescending 介绍    ·Select - Select选择:延迟    ·Where ...

  3. Java并发包下锁学习第二篇Java并发基础框架-队列同步器介绍

    Java并发包下锁学习第二篇队列同步器 还记得在第一篇文章中,讲到的locks包下的类结果图吗?如下图: ​ 从图中,我们可以看到AbstractQueuedSynchronizer这个类很重要(在本 ...

  4. LINQ查询操作符之Select、Where、OrderBy、OrderByDescending、GroupBy、Join、GroupJoin及其对应的查询语法

    介绍    ·Select - Select选择:延迟    ·Where - Where查询:延迟    ·OrderBy - 按指定表达式对集合正序排序:延迟    ·OrderByDescend ...

  5. 在LINQ查询中LINQ之Group By的用法

    LINQ定义了大约40个查询操作符,如select.from.in.where.group 以及order by,借助于LINQ技术,我们可以使用一种类似SQL的语法来查询任何形式的数据.Linq有很 ...

  6. Java泛型学习---第二篇

    泛型学习第一篇 1.泛型之擦拭法 泛型是一种类似"模板代码"的技术,不同语言的泛型实现方式不一定相同. Java语言的泛型实现方式是擦拭法(Type Erasure). 所谓擦拭法 ...

  7. 从.Net到Java学习第二篇——IDEA and start spring boot

    从.Net到Java学习第一篇——开篇 所谓工欲善其事,必先利其器,做java开发也一样,在比较了目前最流行的几个java IDE(eclipse,myeclipse.IDEA)之后,我果断选择IDE ...

  8. Linq专题之提高编码效率—— 第二篇 神一样的匿名类型

    说起匿名类型,我们都知道这玩意都是为linq而生,而且匿名类型给我们带来的便利性大家在实战中应该都体会到了,特别适合于一次性使用,临时 使用这些场景,虽然说是匿名类型,也就是说是有类型的,只是匿名了而 ...

  9. Linq查询操作语句学习

    对于一个集合,我们通常会用foreach或者for循环来判断查找里面的元素. 但这种方法通常会看起来比较复杂,我们可以使用linq. Linq允许编写C#代码以查询数据库相同的方式操作内存数据(写法类 ...

随机推荐

  1. Android-WebView加载网络图片&网页

    加载网络图片: 链接地址:  http://bcs.link-us.com.cn/directBank/newHX149/directBank/h5/www/dist/img/e113.jpg 确保链 ...

  2. UITableView横向滚动

    UITableView 设置 CGRect tableViewRect = CGRectMake(0.0, 0.0, 50.0, 320.0); self.tableView = [[UITableV ...

  3. SQL SERVER的锁机制(一)——概述(锁的种类与范围)

    锁定:通俗的讲就是加锁.锁定是 Microsoft SQL Server 数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制. 定义:当有事务操作时,数据库引擎会要求不同类型的锁定,如相关数 ...

  4. 【Win】Clso QR Tool 二维码小工具

    一个可以生成并识别二维码的windows小工具,纯绿色.不含糖. 可以通过输入文本生成二维码,或者加载本地图片.剪贴板内的图片,直接解析出二维码内容. 支持自定义LOGO. 下载文件 (当前版本:1. ...

  5. ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下

    先简单了解一这个几个 名词的意思. 控制反转(IOC) 依赖注入(DI) 并不是某种技术. 而是一种思想.一种面向对象编程法则 什么是控制反转(IOC)?  什么是依赖注入(DI) 可以点击下面链接 ...

  6. Python3.5 学习二十四

    本节课程大纲: -------------------------------------------------------------------------------------------- ...

  7. Linux系统磁盘与分区管理(7)

    Linux最传统的磁盘文件系统(filesystem)使用的是EXT4格式,所以要了解文件系统就得要由认识EXT4开始,而文件系统是创建在硬盘上面的,因此我们得了解硬盘的物理组成才行,下面我们回来详细 ...

  8. 移动端font-size适配方案

    概述 这是我研究移动端页面时的思考,记录下来供以后开发时参考,相信对其他人也有用.由于我写移动端页面写的还比较少,一些问题都还没遇到,所以我的这篇博文不免有些错误的地方,还请大佬多多指正. 这篇文章是 ...

  9. mybatis四大接口之 ResultSetHandler

    1. 继承结构 2. ResultSetHandler public interface ResultSetHandler { // 将Statement执行后产生的结果集(可能有多个结果集)映射为结 ...

  10. vue 路由传参的三种基本模式

    路由是连接各个页面的桥梁,而参数在其中扮演者异常重要的角色,在一定意义上,决定着两座桥梁是否能够连接成功. 在vue路由中,支持3中传参方式. 场景,点击父组件的li元素跳转到子组件中,并携带参数,便 ...