LINQ标准查询操作符学习笔记四

       11、分区

扩展方法Take()和Skip()等用于分区操作,这些操作可用于数据分页。在下面的Linq查询中,把扩展方法添加到查询最后,Skip()方法或略掉根据分页大小和页数得到的项数,Take()方法根据分页大小提取一定数目的项:

int pagesize = 5;
int numberPages = (int)Math.Ceiling(Formula1.GetChampions().Count / (double)pagesize);//获得页数

for (int i = 0; i < numberPages; i++)
{
    Console.WriteLine("Page {0}", i);
    var racers = (from r in Formula1.GetChampions()
                  orderby r.LastName
                  select r.FirstName + " " + r.LastName)
                      .Skip(i * pagesize) //跳过指定数目的元素
                      .Take(pagesize)  //提取指定数目的元素?
                      .TakeWhile(r => r.Length > 11);  //额外的限制条件
    foreach (var item in racers)
    {
        Console.WriteLine(item);
    }
    Console.WriteLine();
}
Math.Ceiling (Decimal)返回大于或等于指定的十进制数的最小整数。
Math.Ceiling (Double)返回大于或等于该指定双精度浮点数的最小整数。

输出结果是几组赛手。

       12、聚合操作

聚合操作用于对集合项进行简单的运算,返回结果是一个值而不是一组数据。

下面演示使用Count()方法筛选出冠军次数操作3的赛手:

//统计获得冠军次数大于3次的运动员和获胜次数
var query = from r in Formula1.GetChampions()
            where r.Years.Count() > 3
            orderby r.Years.Count() descending
            select new
            {
                Name = r.FirstName + " " + r.LastName,
                TimesChampion = r.Years.Count()
            };
foreach (var item in query)
{
    Console.WriteLine(item.Name + " " + item.TimesChampion.ToString());
}
Console.WriteLine();

又如Sum()方法,返回序列中的所有数字的和。下面的示例演示了使用Sum()方法计算一个国际赢得的比赛次数,首先根据国家对赛手分组,在创建的匿名类中,对Wins属性进行计算:

//计算一个国际获得冠军的总次数
            var countries =
                from c in
                    from r in Formula1.GetChampions()
                    group r by r.Country into c1
                    select new
                    {
                        Country = c1.Key,
                        Wins = (from r1 in c1 select r1.Wins).Sum()
                    }
                orderby c.Wins descending
                select c;

       13、结果转换

查询结果可以通过调用扩展方法转换成其他类型。但是需要注意的是,如果进行了类型转换,Linq查询将会立即执行而不是推迟到访问数据项时才执行。

下面是一个简单的例子:

//简单查询
var query = (from r in Formula1.GetChampions()
             where r.Starts > 150
             orderby r.Starts descending
             select r).ToList();
foreach (var item in query)
{
    Console.WriteLine("{0} {0:S}",item);
}
Console.WriteLine();

//扩展方法查询
var query2 = Formula1.GetChampions()
    .Where(r => r.Starts > 150)
    .OrderByDescending(r => r.Starts)
    .ToList()
    .Select(r => r) ;
foreach (var item in query2)
{
    Console.WriteLine("{0} {0:S}", item);
}
Console.WriteLine();
//生成查找表
var query3 = (from r in Formula1.GetChampions()
              from c in r.Cars
              select new { Car = c, Racer = r })
                  .ToLookup(cr => cr.Car, cr => cr.Racer);
if (query3.Contains("Williams"))
{
    foreach (var item in query3["Williams"])
    {
        Console.WriteLine(item);
    }
}

这里建查询结果使用ToList()方法转换成了List<T>类型。

       14、生成操作符

生成操作符Ranger()、Empty()、Repear()不是扩展方法,而是返回序列的正常静态方法。

下面例子返回一个填充了一个范围数字的变量,使用了Ranger()方法对变量进行填充

//var values = Enumerable.Range(1, 12);
var values = Enumerable.Range(1, 12)
    .Where(r=>r%2 == 0)
    .Select(r => r * 2);
foreach (var item in values)
{
    Console.Write("{0} ",item);
}
Console.WriteLine();


提示:Range()方法不返回填充了所定义值的集合,这个方法与其他方法一样,也推迟执行查询,返回一  个RangeEnumerator,其中只有一个yield return 语句,来递增值。 
可以把该结果与其他扩展方法合并起来,获得另一个结果,例如使用Select()扩展方法: 
Empty()方法返回一个不返回值的迭代器,它可以用于参数需要一个集合,且可以给参数传送空集合的情形。 
Repeat()方法返回一个迭代器,该迭代器把同一个值重复特定的次数。

       15、并行Linq

并行Linq是.Net4新增加的。在.Net 4的System.Linq命名空间中新增加了类ParallelEnumerable,可以分解查询工作使其工作在多个线程上。

这里首先准备一个大型集合,用随机数填充之后使用Linq筛选数据,获取筛选数据的总和。该查询使用where子句定义一个筛选器,汇总值小于20的项,最后使用Sum()方法计算: 

const int arraySize = 100000000;
var data = new int[arraySize];
var r = new Random();
for (int i = 0; i < arraySize; i++)
{
    data[i] = r.Next(40);
}
var sum = (from x in data.AsParallel()
          where arraySize < 20
          select x).Sum();
sum = data.AsParallel().Where(x => x > 20).Select(x => x).Sum();
Console.WriteLine(sum);

可以看出,这里的查询与前面的查询仅仅是使用了AsParallel()方法。

运行这段代码时启动任务管理器就可以看见效果了。此时系统上所有的CPU都处于忙碌状态,如果删除了AsParallel方法,就不会有这个效果了。

 示例代码:http://files.cnblogs.com/zyqgold/MyLinqTest.rar

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值