LINQ基本子句

由于个人在学校没有接触过Linq,而且在工作上运用Linq的时候也比较多,准备把LINQ的相关知识学习整理梳理一遍,希望能填补下这个知识点,也为未来减轻压力。

LINQ查询表达式使用C#常见的语言构造,从外观上看,和我们常用的SQL类似,并且查询表达式中的变量可以用匿名类型,所以在很多情况下,不需要指定变量类型就可以构建LINQ表达式。

LINQ的数据源可以是数据库对象或是XML流等,也可以使实现了IEnumerable或者泛型IEnumberable<T>接口的集合对象。

LINQ的基本语法包含如下的8个上下文关键字,如下:

关键字说明
from指定范围变量和数据源
where根据bool表达式从数据源中筛选数据
select指定查询结果中的元素所具有的类型或表现形式
group对查询结果按照键值进行分组(IGrouping<TKey,TElement>)
into提供一个标识符,它可以充当对join、group或select子句结果的引用
order对查询出的元素进行排序(ascending/descending)
join按照两个指定匹配条件来Equals连接两个数据源
let产生一个用于存储查询表达式中的子表达式查询结果的范围变量

 

 

 

 

 

 

 

 

 

1、From子句:

如果要写一个LINQ表达式,就必须是以from子句开头。


Person person = new Person();
Student student = new Student();
//判断指定的两个成员是否存在继承关系(判断一个类是否可用赋值给另一个类)    --后者继承于前者
bool b1 = typeof(Person).IsAssignableFrom(typeof(Student));    //student继承了person
bool b3 = person.GetType().IsAssignableFrom(student.GetType());//另一种写法
bool b2 = typeof(Itest).IsAssignableFrom(typeof(Teacher));

//判断是否是指定类的实例
bool b4 = typeof(Person).IsInstanceOfType(student);     //结果为true   student继承了person
bool b5 = person.GetType().IsInstanceOfType(student);//另一种写法   GetType当前对象的实例

//判断是否是某个类的子类,非接口
bool b6 = typeof(Student).IsSubclassOf(typeof(Person));

//判断是否是抽象
if (typeof(Drive).IsAbstract)
{
    Console.WriteLine("是抽象的");
}
else
{
    Console.WriteLine("不是抽象的");
}
Console.ReadKey();

 

 

 

 

 

 

//复合from子句
List<Person> personList2 = new List<Person>()
{
    new Person{ Name = "张三", Age = 20, Phone = new List<string>(){"666666","138******"}},
    new Person{ Name = "李四", Age = 21, Phone = new List<string>(){"777777","138******"}},
    new Person{ Name = "王五", Age = 22, Phone = new List<string>(){"888888","138******"}}
};

//person、phone都是查询变量,作用域为当前查询语句
var new_personList2 = from person in personList2
          from phone in person.Phone
          where phone.IndexOf("6666") > -1       //查询个人电话集合以"6666"开头的人
          select person;
foreach (var new_person in new_personList2)
{
    Console.WriteLine("{0} 年龄{1}", new_person.Name, new_person.Age);
    foreach (var person_phone in new_person.Phone)
    {
        Console.WriteLine("电话:{0}", person_phone);
    }
}

Console.ReadKey();

//4多个from子句
var personList3 = from Person person in personList
 where person.Age > 21       //查询集合1年龄超过21的人
 from Person person2 in personList2
 where person2.Age == 21       //查询集合2年龄等于21的人
 select new { person, person2 };//查询结果定制
foreach (var new_person in personList3)
{
    Console.WriteLine("{0}  {1}", new_person.person.Name, new_person.person2.Name);
}

Console.ReadKey();

 

运行结果如下:

2、Where子句:

where子句是LINQ表达式的元素筛选机制,除了开始和结束的位置,它几乎可以出现在LINQ表达式的任意位置上。在一个LINQ表达式中,可以有where子句,也可以没有;可以有一个,也可以有多个;多个where子句之间的逻辑关系相当于逻辑“与”,每个where子句可以包含1个或多个bool逻辑表达式,这些条件成为谓词,谓词逻辑之间用的是“&&”或“||”等而不是SQL中的and 、or。

//自定义函数
static bool Check(string name)
{
    if (name.Substring(0, 1) == "李")
	return false;
    return true;
}

运行结果如下:

 3、Select子句:

在select子句上可以非常灵活的处理查询到的元素,然后再把结果返回。

//常见的where语句
List<Person> personList = new List<Person>()
{
    new Person(){ Name = "张三三", Age = 20, Phone = "555555"},
    new Person(){ Name = "李四", Age = 21, Phone = "666666"},
    new Person(){ Name = "王五", Age = 22, Phone = "777777"}
};

var new_personList = from person in personList
         where (person.Name.Length == 3 || person.Name.Substring(0, 1) == "李") && person.Age > 20       //查询姓名长度为3或姓名以"李"开头且年龄大于20的人
         select new { person.Name, person.Age };
foreach (var new_person in new_personList)
{
    Console.WriteLine("{0},{1}", new_person.Name, new_person.Age);
}

Console.ReadKey();

//在where子句中使用自定义函数
var new_personList2 = from Person person in personList
 where person.Name.Length == 2
 && Check(person.Name)       //查询姓名长度为2且符合自定义函数限定后的人
 select person;
foreach (var new_person in new_personList2)
{
    Console.WriteLine("{0},{1},{2}", new_person.Name, new_person.Age, new_person.Phone);
}
Console.ReadKey();

//动态谓词的筛选
//定义动态谓词数组,在实际开发中可以动态获得
string[] names = { "李四", "XXX", "***", "@@@", "一些敏感词" };

var new_personList3 = from Person person in personList
 where !names.Contains(person.Name)       //查询姓名不包含集合元素的人
 select person;

foreach (var new_person in new_personList3)
{
    Console.WriteLine("{0} 年龄:{1},电话:{2}", new_person.Name, new_person.Age, new_person.Phone);
}
Console.ReadKey();
List<Person> personList = new List<Person>()
            {
                new Person(){ Name = "张三", Age = 20, Phone = "555555"},
                new Person(){ Name = "李四", Age = 21, Phone = "666666"},
                new Person(){ Name = "王五", Age = 22, Phone = "777777"}
            };

            //常见的select语句
            var new_personList = from person in personList
                                 where person.Age >= 22 && person.Age <= 30       //查询年龄大于等于22小于等于30的人
                                 select new { person.Name, person.Age };       //处理查询结果,返回查到的人的姓名和年龄

            foreach (var new_person in new_personList)
            {
                Console.WriteLine(new_person.Name + “ 年龄:” + new_person.Age);
            }
            Console.ReadKey();

            //对查询到的结果集进行替换
            var new_personList2 = from person in personList
                                  where person.Age >= 21 && person.Age <= 30       //查询年龄大于等于22小于等于30的人
                                  select person.Name.Replace("李", "王");       //处理查询结果,返回查到的人的姓名替换后的结果

            foreach (var new_person in new_personList2)
            {
                Console.WriteLine(new_person);
            }
            Console.ReadKey();

            //在select子句中使用自定义函数
            var new_personList3 = from person in personList
                                  where person.Age >= 20 && person.Age <= 21       //查询年龄大于等于20小于等于21的人
                                  select MyDesc(person.Name);       //处理查询结果,返回自定义函数处理后的人的姓名

            foreach (var new_person in new_personList3)
            {
                Console.WriteLine(new_person);
            }
            Console.ReadKey();

            //对查询结果进行投影
            var new_personList4 = from person in personList
                                  where person.Age >= 21 && person.Age <= 22       //查询年龄大于等于21小于等于22的人
                                  select new NewPerson { Name = "我的名字叫:" + person.Name, Age = person.Age + 1 };       //处理查询结果,返回投影结果

            foreach (var new_person in new_personList4)
            {
                Console.WriteLine(new_person.Name + new_person.Age);
            }
            Console.ReadKey();
static string MyDesc(string s)
{
    return s + "好帅";
}

 

 

public class NewPerson
{
	public string Name { get; set; }
	public int Age { get; set; }
}

运行结果如下:

 4、Group子句:

LINQ表达式必须以from子句开头,以select或group子句结束,所以除了使用select来返回结果外,也可以使用group子句来返回元素分组后的结果。group子句返回的是一个基于IGrouping<TKey,TElement>泛型接口的对象序列。

注意:语法和SQL的group有点区别。

            
 

复制代码

复制代码

运行结果如下:

 5、Into子句:

into子句作为一个临时标识符,用于group、select、join子句中充当其结果的引用。

List<Person> personList = new List<Person>()
            {
                new Person(){ Name = "张一", Age = 20, Phone = "333333"},
                new Person(){ Name = "张二", Age = 21, Phone = "444444"},
                new Person(){ Name = "张三", Age = 22, Phone = "555555"},
                new Person(){ Name = "李四", Age = 23, Phone = "666666"},
                new Person(){ Name = "李五", Age = 24, Phone = "777777"},
                new Person(){ Name = "赵六", Age = 25, Phone = "888888"},
                new Person(){ Name = "田七", Age = 26, Phone = "999999"},
            };

            var new_personList = from person in personList
                                 group person by person.Name.Substring(0, 1);       //按姓氏进行分组

            //遍历键值和键值所属元素
            foreach (IGrouping<string, Person> new_person in new_personList)
            {
                Console.WriteLine();
                Console.WriteLine("姓:{0} ", new_person.Key);
                foreach (var p in new_person)
                {
                    Console.WriteLine("{0} 年龄:{1}  电话:{2}", p.Name, p.Age, p.Phone);
                }
            }
            Console.ReadKey();

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

            var new_personList2 = from person in personList
                                  group person by person.Age > 23;       //按年龄是否大于23进行分组

            foreach (IGrouping<bool, Person> new_person in new_personList2)
            {
                Console.WriteLine();
                Console.WriteLine("年龄 {0} 23 ", new_person.Key ? "大于" : "小于");
                foreach (var p in new_person)
                {
                    Console.WriteLine("{0} 年龄:{1}  电话:{2}", p.Name, p.Age, p.Phone);
                }
            }
            Console.ReadKey();
List<Person> personList = new List<Person>()
            {
                new Person(){ Name = "张一", Age = 20, Phone = "333333"},
                new Person(){ Name = "张二", Age = 21, Phone = "444444"},
                new Person(){ Name = "张三", Age = 12, Phone = "555555"},
                new Person(){ Name = "李四", Age = 23, Phone = "666666"},
                new Person(){ Name = "李五", Age = 14, Phone = "777777"},
                new Person(){ Name = "赵六", Age = 25, Phone = "888888"},
                new Person(){ Name = "田七", Age = 16, Phone = "999999"},
            };

            //into用于group子句
            var new_personList = from person in personList
                                 group person by person.Name.Substring(0, 1) into person_group       //相当于分组后的组名
                                 select person_group;

            foreach (var persontGroup in new_personList)
            {
                Console.WriteLine("姓:{0} ", persontGroup.Key);
                foreach (var p in persontGroup)
                {
                    Console.WriteLine("{0} 电话:{1}", p.Name, p.Phone);
                }
            }
            Console.ReadKey();
            Console.WriteLine();

            //select子句中的into子句
            var new_personList2 = from person in personList
                                  select new { NewName = person.Name, NewAge = person.Age } into newperson       //相当于创建一个新的对象
                                  orderby newperson.NewAge
                                  select newperson;
            
            foreach (var persontGroup in new_personList2)
            {
                Console.WriteLine("{0} 年龄:{1}", persontGroup.NewName, persontGroup.NewAge);
            }

            Console.ReadKey();

运行结果如下:

6、OrderBy子句:

按照元素的一个或多个属性对元素进行排序。

List<Person> personList = new List<Person>()
            {
                new Person(){ Name = "张一", Age = 20, Phone = "333333"},
                new Person(){ Name = "张二二", Age = 20, Phone = "444444"},
                new Person(){ Name = "张三", Age = 12, Phone = "555555"},
                new Person(){ Name = "李四", Age = 23, Phone = "666666"},
                new Person(){ Name = "李五", Age = 14, Phone = "777777"},
                new Person(){ Name = "赵六", Age = 25, Phone = "888888"},
                new Person(){ Name = "田七", Age = 16, Phone = "999999"},
            };

            //按照年龄排序
            var new_personList = from person in personList
                                 orderby person.Age       //默认升序ascending,如果要降序要加上descending
                                 select person;

            foreach (var new_person in new_personList)
            {
                Console.WriteLine("{0} 年龄:{1} 电话:{2}", new_person.Name, new_person.Age, new_person.Phone);
            }
            Console.ReadKey();
            Console.WriteLine();

            //按照年龄进行降序排序,按照名字字数进行次要排序
            var new_personList2 = from person in personList
                                  orderby person.Age descending, person.Name.Length descending
                                  select person;

            foreach (var new_person in new_personList2)
            {
                Console.WriteLine("{0} 年龄:{1} 电话:{2}", new_person.Name, new_person.Age, new_person.Phone);
            }
            Console.ReadKey();

运行结果如下:

 7、Let子句:

let子句用于在LINQ表达式中存储子表达式的计算结果。

            List<Person> personList = new List<Person>()
            {
                new Person(){ Name = "张一", Age = 20, Phone = "333333"},
                new Person(){ Name = "张二二", Age = 20, Phone = "444444"},
                new Person(){ Name = "张三", Age = 12, Phone = "555555"},
                new Person(){ Name = "李四", Age = 23, Phone = "666666"},
                new Person(){ Name = "李五", Age = 14, Phone = "777777"},
                new Person(){ Name = "赵六", Age = 25, Phone = "888888"},
                new Person(){ Name = "田七", Age = 16, Phone = "999999"},
            };

            //使用let子句创建范围变量g,并通过g构建查询表达式
            var new_personList = from person in personList
                                 let g = person.Name.Substring(0, 1)
                                 where g == "张" || g == "李"
                                 select person;

            foreach (var new_person in new_personList)
            {
                Console.WriteLine("{0} 年龄:{1} 电话:{2}", new_person.Name, new_person.Age, new_person.Phone);
            }
            Console.ReadKey();
            Console.WriteLine();

            //也可以不使用let,上面的语句等效于下
            var new_personList2 = from person in personList
                                  where person.Name.Substring(0, 1) == "张" || person.Name.Substring(0, 1) == "李"
                                  select person;

            foreach (var new_person in new_personList2)
            {
                Console.WriteLine("{0} 年龄:{1} 电话:{2}", new_person.Name, new_person.Age, new_person.Phone);
            }
            Console.ReadKey();

运行结果如下:

8、Join子句:

join子句能将两个数据源中元素可以进行相等比较的两个属性进行关联。使用equals关键字进行相等比较,而不是常用的双等号。

//定义两个数据源
            List<Person> personList = new List<Person>()
            {
                new Person(){ Name = "张三", Age = 12, Phone = "555555"},
                new Person(){ Name = "李四", Age = 23, Phone = "666666"},
                new Person(){ Name = "王五", Age = 14, Phone = "777777"},
                new Person(){ Name = "赵六", Age = 25, Phone = "888888"},
                new Person(){ Name = "田七", Age = 16, Phone = "999999"},
            };

            List<PersonFile> personFileList = new List<PersonFile>()
            {
                new PersonFile(){ Name = "张三", File = "三好学生"},
                new PersonFile(){ Name = "李四", File = "班长"},
                new PersonFile(){ Name = "王五", File = "学习委员"},
                new PersonFile(){ Name = "赵六", File = "差生"}
            };

            //根据姓名进行内连接
            var new_personList = from person in personList
                                 join file in personFileList on person.Name equals file.Name
                                 select new { Name = person.Name, file = file.File, Age = person.Age };

            foreach (var new_person in new_personList)
            {
                Console.WriteLine("{0} {1} 年龄:{2}", new_person.Name, new_person.file, new_person.Age);
            }
            Console.ReadKey();
            Console.WriteLine();

            //等效于前面的多个from的效果
            var new_personList2 = from person in personList
                                  from file in personFileList
                                  where person.Name == file.Name
                                  select new { Name = person.Name, File = file.File, Age = person.Age };

            foreach (var new_person in new_personList2)
            {
                Console.WriteLine("{0} {1} 年龄:{2}", new_person.Name, new_person.File, new_person.Age);
            }
            Console.ReadKey();
            Console.WriteLine();

            //根据姓名进行分组连接
            var new_personList3 = from person in personList
                                  join file in personFileList on person.Name equals file.Name into person_group
                                  select new { Name = person.Name, Files = person_group };

            foreach (var new_person in new_personList3)
            {
                Console.WriteLine(new_person.Name);
                foreach (var p in new_person.Files)
                {
                    Console.WriteLine(p.File);
                }
            }
            Console.ReadKey();
            Console.WriteLine();

            //根据姓名进行左外连接
            var new_personList4 = from person in personList
                                  join file in personFileList on person.Name equals file.Name into person_group
                                  from position in person_group.DefaultIfEmpty()
                                  select new { Name = person.Name, File = position == null ? "无" : position.File };
            foreach (var new_person in new_personList4)
            {
                Console.WriteLine("{0}  {1}  ", new_person.Name, new_person.File);
            }
            Console.ReadKey();

运行结果如下:

 

 对Linq的基本子句用法学习和总结完毕,还有待继续练习达到灵活运行!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值