您的位置:首页 > 其它

.NET框架-LINQ 9类操作符使用举例

2017-01-11 15:59 295 查看

Linq标准查询操作符

语言集查询 Ganmge hteg.ratedQuw,LINQ,集 成了C#编程语言中的查询语法 ,可 以用相同的语法访问不同的数据源。 LINQ提 供了不同数据源的抽象层 ,所 以可以使用相同的语法。

1筛选操作符

筛选操作符定义了返回元素的条件。

筛选操作符描述
where使用谓词,返回布尔值
OfType< TResult>根据类型筛选元素
应用举例:

where用法:

var racers = from r in Formulal.Racers
where r.Wins > 15 && r.Country == "Brazil" select r;


OfType< T>用法:

object[] data = {"one", 2, "three", 4, 5, "six"};
var rtnData = data.OfType<string>(); //返回类型为string的数据元素集合


2投射操作符

把对象转化为另一个类型的新对象

投射操作符描述
select
selectMany
用法举例:

select用法

var racers = from r in Formulal.Racers
where r.Wins > 15 && r.Country == "Brazil"
select new
{
Name = string.Format("{0} {1}", r.FirstName, r.LastName),
Country = r.Country,
Wins = r.Wins
};   //输出为含有Name,Country,Wins共计3个属性的对象集合


selectMany用法

var ferrariDrivers = Formulal.Racers.
SelectMany(r => r.Cars,
(r, c) => new { Racer = r, Car = c }).
Where(r => r.Car == "Ferrari").
OrderBy(r => r.Racer.LastName).
Select(r => r.Racer.FirstName + " " + r.Racer.LastName);//筛选出驾驶法拉利的选手集合


3排序操作符

改变返回元素的顺序

排序操作符描述
OrderBy升序排序
OrderByDescending降序排序
ThenBy第一次排序结果类似,用第二次升序排序
ThenByDescending第一次排序结果类似,用第二次降序排序
Reverse反转集合中元素的顺序
举例:

var racers = from r in Formulal.Racers
where r.Country == "Brazil"
orderby r.Wins descending
select new
{
Name = string.Format("{0} {1}", r.FirstName, r.LastName),
Country = r.Country,
Wins = r.Wins
};//国家为巴西,按照胜场次数降序排列


4连接运算符

用于合并不直接相关的集合

连接运算符描述
Join可以根据键选择器函数连接连接2个集合
GroupJoin连接两个集合,组合其结果
//Join连接
//获取冠军年份在2003年后的选手
var racer5 = from r in Formulal.Racers
from y in r.Years
where y > 2003
select new
{
Year = y,
Name = string.Format("{0} {1}", r.FirstName, r.LastName)
};
//获取冠军年份在2003年后的团队
var team1 = from r in Formulal.ChampionTeams
from y in r.Years
where y > 2003
select new
{
Year = y,
Name = string.Format("{0}", r.Name)
};
//连接
var racerAndTeams = from r in racer5
join t in team1 on r.Year equals t.Year
select new
{
Yearj= r.Year,
Racerj = r.Name,
Teamj = t.Name
};


结果:

YearjRacerjTeamj
Yearj=2004Racerj=Michael SchumacherTeamj =Ferrari
Yearj=2005Racerj=Fernando AlonsoTeamj =Renault
Yearj=2006Racerj=Fernando AlonsoTeamj =Renault
Yearj=2007Racerj=Kimi RäikkönenTeamj =Ferrari
Yearj=2008Racerj=Lewis HamiltonTeamj =Ferrari
Yearj=2014Racerj=Lewis HamiltonTeamj =Mercedes
Yearj=2015Racerj=Lewis HamiltonTeamj =Mercedes
Yearj=2009Racerj=Jenson ButtonTeamj =Brawn GP
Yearj=2010Racerj=Sebastian VettelTeamj =Red Bull Racing
Yearj=2011Racerj=Sebastian VettelTeamj =Red Bull Racing
Yearj=2012Racerj=Sebastian VettelTeamj =Red Bull Racing
Yearj=2013Racerj=Sebastian VettelTeamj =Red Bull Racing

5组合运算符

把数据放在组中

组合运算符描述
GroupBy组合有公共键的元素
ToLookUp通过创建一个一对多的字典,来组合元素。
GroupBy用法举例:

var countries = from r in Formulal.Racers
group r by r.Country into g
orderby g.Count() descending, g.Key
where g.Count() > 2
select new
{
Country = g.Key,
Count = g.Count()
};//获取冠军次数大于2的国家


结果:

CountryCount
UK10
Brazil3
Finland3
如果分组需要根据多个字段,则应该这样写:

//按组合键分组后,每组元素个数大于2的分组,按降序排序
var rtnByVal1 = from item in dataSource
group item by new { item.Val1, item.Val2 }
into g
where g.Count()>1
orderby g.Count() descending
select g;
//按Val1和Val2组合为字典键,元素个数为值
var dict = rtnByVal1.ToDictionary(g=>g.First(),g=>g.Count());


6量词操作符

如果元素序列满足指定的条件 ,量词操作符就返回布尔值

组合运算符描述
Any确定集合中是否有满足谓词函数的元素
All确定集合中是否都满足谓词函数的元素
Contains检查某个元素是否存在集合中
List<int> intList1 = new List<int>(5) {1, 2, 3, 4, 5};
bool any3 = intList1.Any(r => r == 3);//确定集合中是否有3,返回true
bool any0 = intList1.Any(r => r == 0);//确定集合中是否有0,返回false
bool allMoreZero = intList1.All(r => r > 0);//确定序列中所有元素都满足大于0,返回true
bool allMore2 = intList1.All(r => r > 2); //返回false
bool contains3 = intList1.Contains(3); //元素3是否在集合中,true


7分区操作符

分区操作符,返回一个子集。使用它们可以得到部分结果。

分区运算符描述
Take必须制定提取元素的个数
Skip跳过指定的元素个数,提取其他元素
TakeWhile提取条件为真的元素
SkipWhile跳过条件为真的元素
int pageSize = 5;
int numberPages = (int)Math.Ceiling(Formulal.Racers.Count() / (double)pageSize);
for (int page = 0; page < numberPages; page++)
{
var racersPartition =
(from r in Formulal.Racers
orderby r.LastName, r.FirstName
select r.FirstName + " " + r.LastName).Skip(page * pageSize).Take(pageSize);
}


结果:

Page 0
Fernando Alons
Mario Andretti
Alberto Ascari
Jack Brabham
Jenson Button
Page 1
Jim Clark
Juan Manuel Fa
Nino Farina
Emerson Fittipaldi
Mika Hakkinen
Page 2
Lewis Hamilton
Mike Hawthorn
Damon Hill
Graham Hill
Phil Hill


8集合操作符(Set operators)

集合操作符返回 一 个集合。除了Distinct之外,其他都需要2个集合。

集合操作符描述
Distinct从集合中删除重复的元素
Union返回出现在其中一个集合中的唯一元素
Intersect交集
Except只出现在一个集合中的元素
Zip通过使用指定的谓词函数合并2个集合
应用举例:

List<int> intList1 = new List<int>(5) {1, 2, 3, 4, 5,3};
List<int> intList2 = new List<int>(3) {2, 5, 0};
var delDuplic = intList1.Distinct(); //去重,结果{1,2,3,4,5}
var unionList = intList1.Union(intList2); //并集,结果{1,2,3,4,5,0}
var interList = intList1.Intersect(intList2); //交集,结果{2,5}
var exceptList = intList1.Except(intList2);//差集,结果{1,3,4}
var exceptList2 = intList2.Except(intList1);//差集,结果{0}
var unionList2 = intList1.Zip(intList2,((i1, i2) => i1+", "+i2)); 结果:{{1,2}{2,5}{3,0}}


9元素操作符(Element operators)

这些元素操作符仅返回一 个元素。

元素操作符描述
First返回第一个满足条件的元素
FirstOrDefault返回第一个满足条件的元素,但如果没有找到满足条件的元素,就返回类型的默认值
Last返回最后一个满足条件的元素
LastOrDefault返回最后一个满足条件的元素,但如果没有找到满足条件的元素,就返回类型的默认值
ElementAt指定了要返回的元素的位置
ElementAtOrDefault指定了要返回的元素的位置,但如果没有找到满足条件的元素,就返回类型的默认值
Single只返回一个满足条件的元素,如果有多个满足条件,就抛出一个异常。
SingleOrDefault只返回一个满足条件的元素,但如果没有找到满足条件的元素,就返回类型的默认值
应用举例:

List<int> intList1 = new List<int>(5) { 1, 8, 3, 4, 5, 3 };
int firstMore1 = intList1.First(r => r > 1);//结果:8
int firstMore17 = intList1.FirstOrDefault(r => r > 17); //结果:0(因为不存在)
int lastMore3 = intList1.Last(r => r > 3); //结果5
int last = intList1.ElementAt(2); //结果3,(索引从0开始)


10聚合操作符(Aggregate operators)

聚合操作符计算集合的一个值。利用这些聚合操作符 ,可 以计算所有值的总和、所有元

素的个数、值最大和最小的元素 ,以 及平均值等

聚合操作符描述
Count所有值的个数
Sum所有值的综合
Min所有值的的最小值
Max所有值的的最大值
Average所有值的平均数
public class MyIntClass
{
public string Name { get; set; }
public int Integar { get; set; }

public MyIntClass(string name, int i)
{
this.Name = name;
this.Integar = Integar;
}
}
List<MyIntClass> intList1 = new List<MyIntClass>(5)
{
new MyIntClass("first",1),
new MyIntClass("second",8) ,
new MyIntClass("third",3) ,
new MyIntClass("fourth",4) ,
new MyIntClass("fifth",5) ,
new MyIntClass("sixth",3)
};
int count = intList1.Count;
int sum = intList1.Sum(r=>r.Integar);
int min = intList1.Min(r => r.Integar);
int max = intList1.Max(r => r.Integar);
double average = intList1.Average(r => r.Integar);


11转换操作符(Conversion operators)

转换操作符将集合转换为数组 :IEnumberable、 IList, IDictionary 等。

Conversion operators描述
ToArray集合转化为Array
AsEnumerable返回类型为IEnumerable< T>
ToList集合转化为List
ToDictionary集合转化为Dictionary
Cast< TResult>映射
还是上面的例子

IEnumerable<MyIntClass> ienuList = from r in intList1 where r.Integar > 3 select r; //返回默认的IEnumerable集合
List<MyIntClass> ienuList2 = (from r in intList1 where r.Integar > 3 select r).ToList(); //返回List
MyIntClass[] ienuList2 = (from r in intList1 where r.Integar > 3 select r).ToArray();//返回数组
var dict = (from r in intList1 where r.Integar > 3 select r).ToDictionary(r=>r.Name,r=>r.Integar); //字典,key是name, value:Integar
IEnumerable<MyIntClass> ienuList2 = (from r in intList1 where r.Integar > 3 select r).AsEnumerable();


12生成操作符(Generation operators)

这些生成操作符返回 一 个新集合

Generation operators描述
Empty集合是空的
Range返回一系列数字
Repeat返回始终重复一个值的集合
IEnumerable<int> ints = Enumerable.Range(3, 10);//{3,4,5,6,7,8,9,10,11,12}
IEnumerable<int> emptyInts =  Enumerable.Empty<int>();//生成一个空集合
IEnumerable<int> ints2= Enumerable.Repeat(6,8);//生成8个6的集合


附:展示所用到的实体类和数据

选手实体类

//选手实体类
public class Racer
{
public Racer(string firstName = null, string lastName = null, string country = null, int starts = 0,int wins = 0, IEnumerable<int> years = null, IEnumerable<string> cars = null)
{
this.FirstName = firstName;
this.LastName = lastName;
this.Country = country;
this.Starts = starts;
this.Wins = wins;
var yearList = new List<int>();
if (years != null)
{
foreach (var year in years)
{
yearList.Add(year);
}
this.Years = yearList.ToArray();
}
if (cars != null)
{
var carList = new List<string>();
foreach (var car in cars)
{
carList.Add(car);
}
this.Cars = carList.ToArray();
}

public string FirstName { get; set; }
public string LastName { get; set; }
//赢得比赛的次数
public int Wins { get; set; }
//所属国家
public string Country { get; set; }
//开始做的年龄
public int Starts { get; set; }
//车型数组
public string[] Cars { get; private set; }
//赢得冠军的年份
public int[] Years { get; private set; }
}
}


选手数据

//选手List
public static List<Racer> Racers = new List<Racer>(40)
{
new Racer("Nino", "Farina", "Italy", 33, 5, new int[] { 1950 }, new string[] { "Alfa Romeo" }),
new Racer("Alberto", "Ascari", "Italy", 32, 10, new int[] { 1952, 1953 }, new string[] { "Ferrari" }),
new Racer("Juan Manuel", "Fangio", "Argentina", 51, 24, new int[] { 1951, 1954, 1955, 1956, 1957 }, new string[] { "Alfa Romeo", "Maserati", "Mercedes", "Ferrari" }),
new Racer("Mike", "Hawthorn", "UK", 45, 3, new int[] { 1958 }, new string[] { "Ferrari" }),
new Racer("Phil", "Hill", "USA", 48, 3, new int[] { 1961 }, new string[] { "Ferrari" }),
new Racer("John", "Surtees", "UK", 111, 6, new int[] { 1964 }, new string[] { "Ferrari" }),
new Racer("Jim", "Clark", "UK", 72, 25, new int[] { 1963, 1965 }, new string[] { "Lotus" }),
new Racer("Jack", "Brabham", "Australia", 125, 14, new int[] { 1959, 1960, 1966 }, new string[] { "Cooper", "Brabham" }),
new Racer("Denny", "Hulme", "New Zealand", 112, 8, new int[] { 1967 }, new string[] { "Brabham" }),
new Racer("Graham", "Hill", "UK", 176, 14, new int[] { 1962, 1968 }, new string[] { "BRM", "Lotus" }),
new Racer("Jochen", "Rindt", "Austria", 60, 6, new int[] { 1970 }, new string[] { "Lotus" }),
new Racer("Jackie", "Stewart", "UK", 99, 27, new int[] { 1969, 1971, 1973 }, new string[] { "Matra", "Tyrrell" }),
new Racer("Emerson", "Fittipaldi", "Brazil", 143, 14, new int[] { 1972, 1974 }, new string[] { "Lotus", "McLaren" }),
new Racer("James", "Hunt", "UK", 91, 10, new int[] { 1976 }, new string[] { "McLaren" }),
new Racer("Mario", "Andretti", "USA", 128, 12, new int[] { 1978 }, new string[] { "Lotus" }),
new Racer("Jody", "Scheckter", "South Africa", 112, 10, new int[] { 1979 }, new string[] { "Ferrari" }),
new Racer("Alan", "Jones", "Australia", 115, 12, new int[] { 1980 }, new string[] { "Williams" }),
new Racer("Keke", "Rosberg", "Finland", 114, 5, new int[] { 1982 }, new string[] { "Williams" }),
new Racer("Niki", "Lauda", "Austria", 173, 25, new int[] { 1975, 1977, 1984 }, new string[] { "Ferrari", "McLaren" }),
new Racer("Nelson", "Piquet", "Brazil", 204, 23, new int[] { 1981, 1983, 1987 }, new string[] { "Brabham", "Williams" }),
new Racer("Ayrton", "Senna", "Brazil", 161, 41, new int[] { 1988, 1990, 1991 }, new string[] { "McLaren" }),
new Racer("Nigel", "Mansell", "UK", 187, 31, new int[] { 1992 }, new string[] { "Williams" }),
new Racer("Alain", "Prost", "France", 197, 51, new int[] { 1985, 1986, 1989, 1993 }, new string[] { "McLaren", "Williams" }),
new Racer("Damon", "Hill", "UK", 114, 22, new int[] { 1996 }, new string[] { "Williams" }),
new Racer("Jacques", "Villeneuve", "Canada", 165, 11, new int[] { 1997 }, new string[] { "Williams" }),
new Racer("Mika", "Hakkinen", "Finland", 160, 20, new int[] { 1998, 1999 }, new string[] { "McLaren" }),
new Racer("Michael", "Schumacher", "Germany", 287, 91, new int[] { 1994, 1995, 2000, 2001, 2002, 2003, 2004 }, new string[] { "Benetton", "Ferrari" }),
new Racer("Fernando", "Alonso", "Spain", 252, 32, new int[] { 2005, 2006 }, new string[] { "Renault" }),
new Racer("Kimi", "Räikkönen", "Finland", 230, 20, new int[] { 2007 }, new string[] { "Ferrari" }),
new Racer("Lewis", "Hamilton", "UK", 166, 43, new int[] { 2008, 2014, 2015 }, new string[] { "McLaren", "Mercedes" }),
new Racer("Jenson", "Button", "UK", 283, 15, new int[] { 2009 }, new string[] { "Brawn GP" }),
new Racer("Sebastian", "Vettel", "Germany", 156, 42, new int[] { 2010, 2011, 2012, 2013 }, new string[] { "Red Bull Racing" })

};


团队实体类

[Serializable]
public class Team
{
public Team(string name, params int[] years)
{
this.Name = name;
this.Years = years;
}
public string Name { get; private set; }
public int[] Years { get; private set; }
}


团队数据

//冠军团队List
public static List<Team> ChampionTeams = new List<Team>()
{
new Team("Vanwall", 1958),
new Team("Cooper", 1959, 1960),
new Team("Ferrari", 1961, 1964, 1975, 1976, 1977, 1979, 1982, 1983, 1999, 2000, 2001, 2002, 2003, 2004, 2007,
2008),
new Team("BRM", 1962),
new Team("Lotus", 1963, 1965, 1968, 1970, 1972, 1973, 1978),
new Team("Brabham", 1966, 1967),
new Team("Matra", 1969),
new Team("Tyrrell", 1971),
new Team("McLaren", 1974, 1984, 1985, 1988, 1989, 1990, 1991, 1998),
new Team("Williams", 1980, 1981, 1986, 1987, 1992, 1993, 1994, 1996, 1997),
new Team("Benetton", 1995),
new Team("Renault", 2005, 2006),
new Team("Brawn GP", 2009),
new Team("Red Bull Racing", 2010, 2011, 2012, 2013),
new Team("Mercedes", 2014, 2015)
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: