LINQ学习总结

本文详细介绍了LINQ的学习总结,包括数据源获取、查询创建、方法语法和标准查询运算符。通过`from`、`where`、`orderby`、`group by`等子句进行数据操作,并探讨了`Cast`、`GroupBy`、`Join`等方法。同时,解释了LINQ的执行方式,如即时与推迟执行、流式与非流式处理,以及各种查询运算符的使用示例。
摘要由CSDN通过智能技术生成

获取数据源

语句:from 范围变量 in 数据源

可查询类型(支持IEnumberable或派生接口,如泛型IQueryable 的类型)无需修改或处理就可作为LINQ数据源。
如果源数据不是可查询类型,则LINQ提供程序必须以此方式表示源数据,如下操作。

//LINQ to XML 将 XML 文档加载到可查询的 XElement 类型中
XElement contacts = XElement.Load(@"c:\myContactList.xml");

//LINQ to SQL
Northwnd db = new Northwnd(@"c:\northwnd.mdf");  
IQueryable<Customer> custQuery =  
    from cust in db.Customers  
    where cust.City == "London"  
    select cust;  

可以通过使用let子句引入其他范围变量
在一般情况下,编译器可以直接推断范围变量的类型,而若数据源是非泛型IEnumerable集合,必须显式声明范围变量的类型,如下操作。

//arrayList为非泛型的ArrayList集合
var query=from Student s in arrayList;

创建查询

from子句

from子句

```csharp
var lowNums = from num in numbers
            where num < 5
            select num;
```

复合from子句

```csharp
var scoreQuery = from student in students
                         from score in student.Scores
                            where score > 90
                            select new { Last = student.LastName, score };
```
筛选(where子句)

使用where子句,仅返回表达式为true的元素。可以使用“&&”和“||”应用更多的筛选器表达式。
csharp var queryLondonCustomers = from cust in customers where cust.City == "London" && cust.Name == "Devon" select cust;

orderby子句

对返回的数据排序,ascending为顺序,descending为逆序,默认为顺序

```csharp
class OrderbySample1
{
    static void Main()
    {
        // Create a delicious data source.
        string[] fruits = { "cherry", "apple", "blueberry" };

        // 顺序排序.
        IEnumerable<string> sortAscendingQuery =
            from fruit in fruits
            orderby fruit //"ascending" is default
            select fruit;
    }
}
/* Output:
Ascending:
apple
blueberry
cherry
```

///Dictionary例子
 public static void Main(string[] args)
        {
            Dictionary<int, string> dictionary = new Dictionary<int, string> {
  {1, "cherry"},{3,"apple"},{2,"blueberry"}};
            IOrderedEnumerable<KeyValuePair<int, string>> sortAscendingQuery =
                from fruit in dictionary
                orderby fruit.Key//"ascending" is default
                select fruit;
            // Solution solution = new Solution();
            // int x = solution.MakeStringSorted("cdbea");
            foreach (var valuePair in sortAscendingQuery)
            {
                Console.WriteLine(valuePair.Value);
            }
}
/* Output:
cherry
blueberry
apple
group by子句

语句:group item by key
根据指定的键分组

```csharp
var queryCustomersByCity =
      from cust in customers
      group cust by cust.City;

foreach (var customerGroup in queryCustomersByCity)
  {
      Console.WriteLine(customerGroup.Key);
      foreach (Customer customer in customerGroup)
      {
          Console.WriteLine("    {0}", customer.Name);
      }
  }



///Dictionary例子
public static void Main(string[] args)
        {
            Dictionary<int, string> dictionary = new Dictionary<int, string> {
  {1, "aa"},{3,"bb"},{2,"aa"}};
            var queryCustomersByCity =
                from cust in dictionary
                group cust by cust.Value;
	
            foreach (var customerGroup in queryCustomersByCity)
            {
                Console.WriteLine(customerGroup.Key);
                foreach (var item in customerGroup)
                {
                    Console.WriteLine("    {0}", item.Key);
                }
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

Output:
aa
    1
    2
bb
    3

如上操作的结果为列表形式,列表元素带有Key,所有元素根据key来分组。

语句:group item by key into group
使用into可以得到范围变量,能直接引用某个组操作

```csharp
// custQuery is an IEnumerable<IGrouping<string, Customer>>
var custQuery =
    from cust in customers
    group cust by cust.City into custGroup
    where custGroup.Count() > 2
    orderby custGroup.Key
    select custGroup;
```


///Dictionary例子
 public static void Main(string[] args)
        {
            Dictionary<int, string> dictionary = new Dictionary<int, string> {
  {3,"bb"},{2,"aa"},{1, "aa"}};
            var queryCustomersByCity =
                from cust in dictionary
                group cust by cust.Value into custGroup
                    orderby custGroup.Key
                        select custGroup;
	
            foreach (var customerGroup in queryCustomersByCity)
            {
                Console.WriteLine(customerGroup.Key);
                foreach (var item in customerGroup)
                {
                    Console.WriteLine("    {0}", item.Key);
                }
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

Output:
aa
    2
    1
bb
    3
join子句

语句:join item in itemResource on item.property equals preItem.property
在 LINQ 中,join 子句始终作用于对象集合,而非直接作用于数据库表。

```csharp
//查找所有位置相同的客户和分销商
var innerJoinQuery =
    from cust in customers
    join dist in distributors on cust.City equals dist.City
    select new { CustomerName = cust.Name, DistributorName = dist.Name };


///Dictionary例子
 public static void Main(string[] args)
        {

            Dictionary<int, Customer> customers = new Dictionary<int, Customer>
            {
                {1, new Customer() {city = "hangzhou", name = "wry"}},
                {2, new Customer() {city = "ningbo", name = "wry2"}}
            };
            Dictionary<int,Distributor> distributors = new Dictionary<int, Distributor>
            {
                {1, new Distributor() {city = "hangzhou", name = "wry3"}},
                {2, new Distributor() {city = "ningbo", name = "wry4"}}
            };

            var queryCustomersByCity =
                from cust in customers
                join distributor in distributors on cust.Value.city equals distributor.Value.city
                select new {CustName = cust.Value.name, DistName = distributor.Value.name};

            foreach (var item in queryCustomersByCity)
            {
                Console.WriteLine("{0} {1}",item.CustName,item.DistName);
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

Output:
wry wry3
wry2 wry4
Press any key to exit

	```
select子句

查询表达式必须以 select 子句或 group 子句结尾。 在最简单的情况下,select 子句仅指定范围变量, 这时返回的序列包含与数据源类型相同的元素。此外,select 子句还提供了强大的机制,用于将源数据转换(或投影)为新类型。

```csharp
var query = from cust in Customer  
            select new {Name = cust.Name, City = cust.City};

///Dictionary例子
 public static void Main(string[] args)
        {

            Dictionary<int, Customer> customers = new Dictionary<int, Customer>
            {
                {1, new Customer() {city = "hangzhou", name = "wry"}},
                {2, new Customer() {city = "ningbo", name = "wry2"}}
            };
            Dictionary<int,Distributor> distributors = new Dictionary<int, Distributor>
            {
                {1, new Distributor() {city = "hangzhou", name = "wry3"}},
                {2, new Distributor() {city = "ningbo", name = "wry4"}}
            };

            var queryCustomersByCity =
                from cust in customers
                join distributor in distributors on cust.Value.city equals distributor.Value.city
                select new {CustName = cust.Value.name, DistName = distributor.Value.name};

            foreach (var item in queryCustomersByCity)
            {
                Console.WriteLine("{0} {1}",item.CustName,item.DistName);
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

Output:
wry wry3
wry2 wry4
Press any key to exit

```

方法语法

上述的方法皆属于查询语法。查询语法和方法语法在语义上是相同的,但是查询语法更简单且更易于阅读。 某些查询必须表示为方法调用(比如.Count()的查询)。

```csharp
//查询语法:
        IEnumerable<int> numQuery1 =
            from num in numbers
            where num % 2 == 0
            orderby num
            select num;

        //方法语法:
        IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);


///Dictionary例子
//查询语法:
Dictionary<int, int> dictionary = new Dictionary<int, int>();
            dictionary.Add(1,7);
            dictionary.Add(2,2);
            dictionary.Add(3,8);
            dictionary.Add(4,3);
            dictionary.Add(5,4);
            IOrderedEnumerable<KeyValuePair<int, int>> numQuery1 =
                from num in dictionary
                where num.Value % 2 == 0
                orderby num.Value
                select num;
            foreach (var item in numQuery1)
            {
                Console.WriteLine("{0}",item.Key);
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();

Output:
2
5
3

//方法语法
Dictionary<int, int> dictionary = new Dictionary<int, int>();
            dictionary.Add(1,7);
            dictionary.Add(2,2);
            dictionary.Add(3,8);
            dictionary.Add(4,3);
            dictionary.Add(5,4);
      
            IOrderedEnumerable<KeyValuePair<int, int>> numQuery2 = dictionary.Where(num => num.Value % 2 == 0)
                .OrderBy(num => num.Value);
            foreach (var item in numQuery2)
            {
                Console.WriteLine("{0}",item.Key);
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();

Output:
2
5
3

标准查询运算符

Cast

执行方式:流式处理
将 IEnumerable 的元素强制转换为指定的类型。

```csharp
IEnumerable<string> query =
    fruits.Cast<string>().OrderBy(fruit => fruit).Select(fruit => fruit);

///Dictionary例子
 Dictionary<int, string> dictionary = new Dictionary<int, string>();
            dictionary.Add(1,"aa");
            dictionary.Add(2,"cc");
            dictionary.Add(3,"bb");
            dictionary.Add(4,"ff");
            dictionary.Add(5,"ee");
            var numQuery2 = dictionary.Cast<KeyValuePair<int,string>>().OrderBy(num => num.Value);
            foreach (var item in numQuery2)
            {
                Console.WriteLine(item.Key);
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();

Output:
1
3
2
5
4
Press any key to exit

```
GroupBy

执行方式:非流式处理
根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。 通过使用指定的函数对每个组的元素进行投影。
```csharp
public static void GroupByEx4()
{
// Create a list of pets.
List petsList =
new List{ new Pet { Name=“Barley”, Age=8.3 },
new Pet { Name=“Boots”, Age=4.9 },
new Pet { Name=“Whiskers”, Age=1.5 },
new Pet { Name=“Daisy”, Age=4.3 } };
var query = petsList.GroupBy(
pet => Math.Floor(pet.Age), //key
pet => pet.Age, //element
(baseAge, ages) => new
{
Key = baseAge,
Count = ages.Count(),
Min = ages.Min(),
Max = ages.Max()
}); //结果集(key,IEnumerable groupList)

    // Iterate over each anonymous type.
    foreach (var result in query)
    {
        Console.WriteLine("\nAge group: " + result.Key);
        Console.WriteLine("Number of pets in this age group: " + result.Count);
        Console.WriteLine("Minimum age: " + result.Min);
        Console.WriteLine("Maximum age: " + result.Max);
    }

    /*  This code produces the following output:

        Age group: 8
        Number of pets in this age group: 1
        Minimum age: 8.3
        Maximum age: 8.3

        Age group: 4
        Number of pets in this age group: 2
        Minimum age: 4.3
        Maximum age: 4.9

        Age group: 1
        Number of pets in this age group: 1
        Minimum age: 1.5
        Maximum age: 1.5
    */



///Dictionary例子
Dictionary<int, string> dictionary = new Dictionary<int, string>();
            dictionary.Add(1,"aa");
            dictionary.Add(2,"cc");
            dictionary.Add(3,"aa");
            dictionary.Add(4,"cc");
            dictionary.Add(5,"ee");
            var numQuery2 = dictionary.GroupBy(item => item.Value);
            foreach (var group in numQuery2)
            {
                Console.WriteLine(group.Key);
                foreach (var item in group)
                {
                    Console.WriteLine("     {0}",item.Key);
                }
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();

Output:
aa
     1
     3
cc
     2
     4
ee
     5
Press any key to exit

```
GroupJoin

执行方式:流式处理和非流式处理
基于键值等同性对两个序列的元素进行关联,并对结果进行分组。 使用指定的 IEqualityComparer 对键进行比较。

```csharp
	Person magnus = new Person { Name = "Hedlund, Magnus" };
    Person terry = new Person { Name = "Adams, Terry" };
    Person charlotte = new Person { Name = "Weiss, Charlotte" };

    Pet barley = new Pet { Name = "Barley", Owner = terry };
    Pet boots = new Pet { Name = "Boots", Owner = terry };
    Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
    Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

    List<Person> people = new List<Person> { magnus, terry, charlotte };
    List<Pet> pets = new List<Pet> { barley, boots, whiskers, daisy };
    var query =                                        //返回IEnumerable<result>
        people.GroupJoin(pets,                         //要联接的序列
                         person => person,             //第一个序列中提取联接键,按键分组
                         pet => pet.Owner,             //第二个序列中提取联接键
                         (person, petCollection) =>    //创建结果元素
                             new
                             {
                                 OwnerName = person.Name,
                                 Pets = petCollection.Select(pet => pet.Name)
                             });
	foreach (var obj in query)
    {
        // Output the owner's name.
        Console.WriteLine("{0}:", obj.OwnerName);
        // Output each of the owner's pet's names.
        foreach (string pet in obj.Pets)
        {
            Console.WriteLine("  {0}", pet);
        }
    }

	/*
	 This code produces the following output:
	
	 Hedlund, Magnus:
	   Daisy
	 Adams, Terry:
	   Barley
	   Boots
	 Weiss, Charlotte:
	   Whiskers
	*/


	
	///Dictionary例子
	Dictionary<int, Customer> customers = new Dictionary<int, Customer>
	            {
	                {1, new Customer() {city = "hangzhou", name = "wry"}},
	                {2, new Customer() {city = "ningbo", name = "wry2"}}
	            };
	            Dictionary<int,Distributor> distributors = new Dictionary<int, Distributor>
	            {
	                {1, new Distributor() {city = "hangzhou", name = "wry3"}},
	                {2, new Distributor() {city = "ningbo", name = "wry4"}}
	            };
	            var query = customers.GroupJoin(distributors,
	                custCity => custCity.Value.city,
	                distCity => distCity.Value.city,
	                (custName, collection) =>
	                    new
	                    {
	                        custN = custName.Value.name,
	                        distN = collection.Select(dist => dist.Value.name)
	                    }
	            );
	            foreach (var group in query)
	            {
	                Console.WriteLine(group.custN);
	                foreach (var item in group.distN)
	                {
	                    Console.WriteLine("     {0}",item);
	                }
	            }
	            Console.WriteLine("Press any key to exit");
	            Console.ReadKey();
	
	Output:
	wry
	     wry3
	wry2
	     wry4
	Press any key to exit

```
Join

执行方式:流式处理与非流式处理
基于匹配键对两个序列的元素进行关联。

```csharp
	var query =
        people.Join(pets,								//要联接的序列
                    person => person,					//第一个序列中提取联接键
                    pet => pet.Owner,					//第二个序列中提取联接键
                    (person, pet) =>					//创建结果元素
                        new { OwnerName = person.Name, Pet = pet.Name });


///Dictionary例子
Dictionary<int, Customer> customers = new Dictionary<int, Customer>
            {
                {1, new Customer() {city = "hangzhou", name = "wry"}},
                {2, new Customer() {city = "ningbo", name = "wry2"}}
            };
            Dictionary<int,Distributor> distributors = new Dictionary<int, Distributor>
            {
                {1, new Distributor() {city = "hangzhou", name = "wry3"}},
                {2, new Distributor() {city = "ningbo", name = "wry4"}}
            };
            var query = customers.Join(distributors,
                custCity => custCity.Value.city,
                distCity => distCity.Value.city,
                (custName, distName) =>
                    new
                    {
                        custN = custName.Value.name,
                        distN = distName.Value.name
                    }
            );
            foreach (var group in query)
            {
                Console.WriteLine("{0}     {1}",group.custN,group.distN);
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();

		Output:
		wry     wry3
		wry2     wry4
		Press any key to exit

```
OrderBy

执行方式:非流式处理
根据键按升序对序列的元素进行排序。

```csharp
IEnumerable<Pet> query = pets.OrderBy(pet => pet.Age);

	///Dictionary例子
	 Dictionary<int, string> dictionary = new Dictionary<int, string>();
	            dictionary.Add(1,"aa");
	            dictionary.Add(2,"cc");
	            dictionary.Add(3,"bb");
	            dictionary.Add(4,"ff");
	            dictionary.Add(5,"ee");
	            var numQuery2 = dictionary.Cast<KeyValuePair<int,string>>().OrderBy(num => num.Value);
	            foreach (var item in numQuery2)
	            {
	                Console.WriteLine(item.Key);
	            }
	            Console.WriteLine("Press any key to exit");
	            Console.ReadKey();
	
	Output:
	1
	3
	2
	5
	4
	Press any key to exit
```
OrderByDescending

执行方式:非流式处理
根据键按降序对序列的元素进行排序。

```csharp
IEnumerable<Pet> query = pets.OrderByDescending(pet => pet.Age);


///Dictionary例子
Dictionary<int, string> dictionary = new Dictionary<int, string>();
            dictionary.Add(1,"aa");
            dictionary.Add(2,"cc");
            dictionary.Add(3,"bb");
            dictionary.Add(4,"ff");
            dictionary.Add(5,"ee");
            var numQuery2 = dictionary.Cast<KeyValuePair<int,string>>().OrderByDescending(num => num.Value);
            foreach (var item in numQuery2)
            {
                Console.WriteLine(item.Key);
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();

Output:
4
5
2
3
1
Press any key to exit

```
ThenBy

执行方式:非流式处理
根据某个键按升序对序列中的元素执行后续排序。

```csharp
IEnumerable<string> query =
    fruits.OrderBy(fruit => fruit.Length).ThenBy(fruit => fruit);

///Dictionary例子
 Dictionary<int, string> dictionary = new Dictionary<int, string>();
            dictionary.Add(2,"aa");
            dictionary.Add(4,"aa");
            dictionary.Add(1,"aa");
            dictionary.Add(3,"bb");
            dictionary.Add(5,"bb");
            var numQuery2 = dictionary.Cast<KeyValuePair<int,string>>().OrderBy(num => num.V
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值