LINQ查询表达式

约束

LINQ查询表达式必须以from子句开头,以select或group子句结束

关键字

from...in...:指定要查找的数据以及范围变量,多个from子句则表示从多个数据源查找数据。注意:C#编译器会把"复合from子句"的查询表达式转换为SelectMany()扩展方法

join...in...on...equals...:指定多个数据源的关联方式

let:引入用于存储查询表达式中子表达式结果的范围变量,通常能达到层次感会更好,使代码更易于月的

orderby、descending:指定元素的排序字段和排序方式,当有多个排序字段时,由字段顺序确定主次关系,可指定升序和降序两种排序方式

where:指定元素的筛选条件,多个where子句则表示了并列条件,必须全部都满足才能入选,每个where子句可以使用&&、||连接多个条件表达式

group:指定元素的分组字段

select:指定查询要返回的目标数据,可以指定任何类型,甚至是匿名类型(目前通常被指定为匿名类型)

into:提供一个临时的标识符,该标识符可以引用join、group和select子句的结果。(1)直接出现在join子句之后的into关键字会被翻译为GroupJoin。(2)select或group子句字后的into它会重新开始一个查询,让我们可以继续引入where、orderby和select子句,它是对分步构建查询表达式的一种简写方式。

下面通过一个案例来学习对两张表进行查询

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace _013_LINQ {
/// <summary>
/// 武林高手
/// </summary>
class MartialArtsMaster {
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Menpai { get; set; }
public string Kongfu { get; set; }
public int Level { get; set; } public override string ToString()
{
return string.Format("Id: {0}, Name: {1}, Age: {2}, Menpai: {3}, Kongfu: {4}, Level: {5}", Id, Name, Age, Menpai, Kongfu, Level);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace _013_LINQ {
/// <summary>
/// 武学
/// </summary>
class Kongfu {
public int Id { get; set; }
public string Name { get; set; }
public int Power { get; set; } public override string ToString()
{
return string.Format("Id: {0}, Name: {1}, Power: {2}", Id, Name, Power);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks; namespace _013_LINQ
{
internal class Program
{
private static void Main(string[] args)
{
//初始化武林高手
var masterList = new List<MartialArtsMaster>()
{
new MartialArtsMaster() {Id = 1, Name = "黄蓉", Age = 18, Menpai = "丐帮", Kongfu = "打狗棒法", Level = 9},
new MartialArtsMaster() {Id = 2, Name = "洪七公", Age = 70, Menpai = "丐帮", Kongfu = "打狗棒法", Level = 10},
new MartialArtsMaster() {Id = 3, Name = "郭靖", Age = 22, Menpai = "丐帮", Kongfu = "降龙十八掌", Level = 10},
new MartialArtsMaster() {Id = 4, Name = "任我行", Age = 50, Menpai = "明教", Kongfu = "葵花宝典", Level = 1},
new MartialArtsMaster() {Id = 5, Name = "东方不败", Age = 35, Menpai = "明教", Kongfu = "葵花宝典", Level = 10},
new MartialArtsMaster() {Id = 6, Name = "林平之", Age = 23, Menpai = "华山", Kongfu = "葵花宝典", Level = 7},
new MartialArtsMaster() {Id = 7, Name = "岳不群", Age = 50, Menpai = "华山", Kongfu = "葵花宝典", Level = 8},
new MartialArtsMaster() {Id = 8, Name = "令狐冲", Age = 23, Menpai = "华山", Kongfu = "独孤九剑", Level = 10},
new MartialArtsMaster() {Id = 9, Name = "梅超风", Age = 23, Menpai = "桃花岛", Kongfu = "九阴真经", Level = 8},
new MartialArtsMaster() {Id = 10, Name = "黄药师", Age = 23, Menpai = "梅花岛", Kongfu = "弹指神通", Level = 10},
new MartialArtsMaster() {Id = 11, Name = "风清扬", Age = 23, Menpai = "华山", Kongfu = "独孤九剑", Level = 10}
};
//初始化武学
var kongfuList = new List<Kongfu>()
{
new Kongfu() {Id = 1, Name = "打狗棒法", Power = 90},
new Kongfu() {Id = 2, Name = "降龙十八掌", Power = 95},
new Kongfu() {Id = 3, Name = "葵花宝典", Power = 100},
new Kongfu() {Id = 4, Name = "独孤九剑", Power = 100},
new Kongfu() {Id = 5, Name = "九阴真经", Power = 100},
new Kongfu() {Id = 6, Name = "弹指神通", Power = 100}
};
}

上面定义了两个类,武林高手和武学,现在我们查询所有武学级别大于8且门派为丐帮的武林高手。

首先我们使用原始的方法来查询:

{
var res = new List<MartialArtsMaster>();
foreach (var temp in masterList)
{
if (temp.Level > 8 && temp.Menpai == "丐帮")
{
res.Add(temp);
}

1 使用LINQ查询,表达式写法

            //1,使用LINQ做查询( 表达式写法)
var res = from m in masterList
//from后面设置查询的集合
where m.Level > 8 && m.Menpai == "丐帮"
//where后面跟上查询的条件
select m;//表示m的结果结合返回

使用LINQ查询,扩展方法的写法。其中Where是过滤操作符,根据返回bool值的Func委托参数过滤元素

        //过滤方法
static bool Test1(MartialArtsMaster master)
{
if (master.Level > 8) return true;
return false;
} //2,扩展方法的写法
//var res = masterList.Where(Test1);
var res = masterList.Where(m => m.Level > 8 && m.Menpai == "丐帮");

查询结果:

LINQ也可以同时查多个表,下面我们取得所学功夫的杀伤力大于90 的武林高手。

2 LINQ 联合查询

            var res = from m in masterList
from k in kongfuList
where m.Kongfu == k.Name && k.Power > 90
select m;

LINQ 联合查询,扩展方法用法

            var res =
masterList.SelectMany(m => kongfuList, (m, k) => new { master = m, kongfu = k })
.Where(x => x.master.Kongfu == x.kongfu.Name && x.kongfu.Power > 90);

查询结果:

3 对查询结果做排序 orderby (descending)

优先等级排序,然后年龄排序

            var res = from m in masterList
where m.Level > 8 && m.Menpai == "丐帮"
//orderby m.Age descending // 默认从小到大,加上descending从大到小
orderby m.Level, m.Age //按照多个字段进行排序,如果字段的属性相同,就按照第二个属性排序
select m;//表示m的结果结合返回

排序扩展用法

var res = masterList.Where(m => m.Level > 8 && m.Menpai == "丐帮").OrderBy(m => m.Age);

如果排序判断条件有多个,后面的排序要用ThenBy

var res = masterList.Where(m => m.Level > 8).OrderBy(m => m.Level).ThenBy(m => m.Age);

查询结果:

4 Join on集合联合查询

            var res = from m in masterList
// join...in... 表示要连接的表,on后面为连接条件,等于要用equals,不能用==
join k in kongfuList on m.Kongfu equals k.Name
where k.Power > 90
select new { master = m, kongfu = k };

查询结果:

5 分组查询 into groups

把武林高手按照所学功夫分类,看一下那个功夫修炼的人数最多

            var res = from k in kongfuList
join m in masterList on k.Name equals m.Kongfu
into groups //分组
orderby groups.Count() // 这个可以获得数量
select new { kongfu = k, count = groups.Count() };

查询结果:

6 按照自身字段分组 group by

            var res = from m in masterList
group m by m.Kongfu
into g
select new { count = g.Count(), key = g.Key };//g.Key Key表示是按照那个属性分的组

结果:

7 量词操作符 any all   判断集合中是否满足某个条件

any判断集合中是否有一个满足,all判断集合中是否全部满足

            bool res = masterList.Any(m => m.Menpai == "长留");
Console.WriteLine(res);
res = masterList.All(m => m.Menpai == "丐帮");
Console.WriteLine(res);

结果:

C#编程 LINQ查询的更多相关文章

  1. LINQ 查询表达式(C# 编程指南)

    语言集成查询 (LINQ) 是一组技术的名称,这些技术建立在将查询功能直接集成到 C# 语言(以及 Visual Basic 和可能的任何其他 .NET 语言)的基础上.  借助于 LINQ,查询现在 ...

  2. Linq查询表达式

    目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. ...

  3. 使用Expression Tree构建动态LINQ查询

    这篇文章介绍一个有意思的话题,也是经常被人问到的:如何构建动态LINQ查询?所谓动态,主要的意思在于查询的条件可以随机组合,动态添加,而不是固定的写法.这个在很多系统开发过程中是非常有用的. 我这里给 ...

  4. Linq查询简介

    查询是一种从数据源检索数据的表达式. 查询通常用专门的查询语言来表示. 随着时间的推移,人们已经为各种数据源开发了不同的语言:例如,用于关系数据库的 SQL 和用于 XML 的 XQuery. 因此, ...

  5. Linq学习之旅——LINQ查询表达式

    1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. 概述 ...

  6. C#高级知识点概要(3) - 特性、自动属性、对象集合初始化器、扩展方法、Lambda表达式和Linq查询

    1.特性(Attributes) 特性(Attributes),MSDN的定义是:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法 ...

  7. 2.3 LINQ查询表达式中 使用select子句 指定目标数据

    本篇讲解LINQ查询的三种形式: 查询对象 自定义查询对象某个属性 查询匿名类型结果 [1.查询结果返回集合元素] 在LINQ查询中,select子句和from子句都是必备子句.LINQ查询表达式必须 ...

  8. 1.3 LINQ查询

    LINQ最具突破性的优势在于将文本查询与对象操作完美集成,它让查询数据和操作对象一样安全和轻松.查询(Query)是LINQ的核心概念之一. 传统意义上的数据查询语言,通常是比较易懂,具有一定语义的文 ...

  9. Linq查询连接guid与varchar字段

    使用场景 在数据库设计中进场会出现一些通用表,如通用附件表,一般都是通过ForeignTable(关联的表名)和ForeignKey(关联表的主键)与其他表关联.这样的表在数据库中没有外键关系,而且一 ...

随机推荐

  1. Android之View的内容

    View的事件体系 本章介绍View的事件分发和滑动冲突问题的解决方案. 3.1 view的基础知识 View的位置参数.MotionEvent和TouchSlop对象.VelocityTracker ...

  2. Python学习笔记——文件系统

    文件系统 import os # 打印当前目录 print(os.getcwd()) # 列出当前目录的所有文件 print(os.listdir()) F:\codes\python\python\ ...

  3. CF1190D Tokitsukaze and Strange Rectangle

    思路: 线段树 + 扫描线. 实现: #include <bits/stdc++.h> using namespace std; typedef long long ll; ; int n ...

  4. 【VS开发】C/C++预编译命令

    C/C++中宏总结C程序的源代码中可包括各种编译指令,这些指令称为预处理命令或预处理器.虽然它们实际上不是C语言的一部分,但却扩展了C程 序设计的环境. 预处理指令的主要作用就是把通过预处理的内建功能 ...

  5. 如何运行spring boot 工程

    1.右键工程,Run As, Maven install, 2.右键工程,Run As,Spring Boot App 3.在地址栏输入127.0.0.1:8080 动图示例

  6. 幻数浅析(Magic Number)

    在源代码编写中,有这么一种情况:编码者在写源代码的时候,使用了一个数字,比如0x2123,0.021f等,他当时是明白这个数字的意思的,但是别的程序员看他的代码,可能很难理解,甚至,过了一段时间,代码 ...

  7. MIT 6.828 课程介绍

    MIT 6.828 课程介绍 本文是对MIT 6.828操作系统课程介绍的简单摘录,详细介绍见6.828: Learning by doing以及朱佳顺的推荐一门课:6.828.学习资源均可以在课程主 ...

  8. NAT 模式下有两个虚拟机 网段不一样,一台可上网,可ping通,一台上不了网且ping不通

    NAT 模式下有两个虚拟机 网段不一样,一台可上网,可ping通,一台上不了网且ping不通直接修改网段的话,会登录不上去,解决方法:设置>网络适配器>高级>生成mac地址重新登陆即 ...

  9. vim 插件 入门

    vim 手册 vimtutor 精简版本 help user-manual 详细手册 一些vim自带设置 set nu "显示行号 set cursorline "高亮显示当前行 ...

  10. Python 常用内置模块详解

    Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...