2024年最新C#进阶-LINQ表达式总结_c#连接数据库linq语句(2),2024年最新拼多多hr面试

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

/* C#版本1 /
List userList = (from u in list where u.name.Contains(“Jin”) orderby u.age descending orderby u.name select u).ToList();
/
C#版本2 */
List userList = list.Where(u => u.name.Contains(“Jin”)).OrderByDescending(u => u.age).OrderBy(u => u.name).ToList();

{id = 10, name = Hu Jin, age = 21, gender = False, occupation = Student},
{id = 7, name = Liu Jin, age = 21, gender = True, occupation = Builder},
{id = 2, name = Zhang Jin, age = 18, gender = False, occupation = Student} /* 输出结果 */


6、Any/All 函数

Any()函数判断判断是否至少存在一个符合元素符合条件;All()函数判断是否全部元素都符合条件;下面以Any()函数为例:

/* SQL里的表达: 查找用户里是否存在年龄小于30岁职业是医生的女性 /
select count(
) from user where occupation = “Doctor” and gender = false and age < 30; //返回符合的个数

/* C#版本1 /
bool result = (from u in list where u.age < 30 where !u.gender where u.occupation == “Doctor” select u).Any();
/
C#版本2 */
bool result = list.Any(u => u.age < 30 && !u.gender && u.occupation == “Doctor”);

数据源中所有医生如下:

CKT5VEQ3TLIX0X9R - C#进阶-LINQ表达式基础语法Ⅱ

可以看到,目前我们数据源里是有Liu Shuai这一条符合三个属性(小于30岁/医生/女性)的。

true /* 输出结果 */

这里Any()函数是只要存在至少一个符合全部条件的结果,即返回布尔值True,只有在一个都不符合条件的情况下才会返回False;与之相反,All()函数只有在全部数据都符合全部条件的情况下,才会返回True,只要有一条不满足就返回False;All()函数的语法和Any()函数的语法相同,上面的例子把Any()直接替换成All()即可。


7、Single/Default****函数

Single()判断是否只有一个元素符合条件,若成立则返回该元素,若不成立则抛出异常。

/* SQL里的表达: 查找用户里年龄小于30岁职业是医生的女性 */
select * from user where occupation = “Doctor” and gender = false and age < 30

/* C#版本1 /
User userResult = (from u in list where u.age < 30 where !u.gender where u.occupation == “Doctor” select u).Single();
/
C#版本2 */
User userResult = list.Single(u => u.age < 30 && !u.gender && u.occupation == “Doctor”);

{id = 6, name = Liu Shuai, age = 29, gender = False, occupation = Doctor} /* 输出结果 */

Single()要求有且只有一条满足要求的数据,多条满足条件或一条也没有,此方法会报错;
SingleOrDefault()要求最多有一条满足要求的数据,多条满足条件,此方法会报错;没有数据则返回数据类型的默认值;
类似的还有First()、FirstOrDefault()、Last()、LastOrDefault(),这里给大家做了一个异常表格记录了各种情况的返回值:

函数没有满足一条满足多条满足list本身为Null
Single异常该元素异常异常
SingleOrDefault默认值该元素异常异常
First异常该元素第一个元素异常
FirstOrDefault默认值该元素第一个元素异常
Last异常该元素末尾的元素异常
LastOrDefault默认值该元素末尾的元素异常

面对可能出现的异常,我们一般在使用这类方法时要进行Try{…}Catch(…){…}。


8、Skip/Take/Top 函数

/* SQL里的表达: 查找用户表自然排序第4个人到第6个人的姓名*/
select name from user limit 3,3;

/* C#版本1 /
List nameList = (from u in list select u.name).Skip(3).Take(3).ToList();
/
C#版本2 */
List nameList = list.Skip(3).Take(3).Select(x => x.name).ToList();

Liu Guangzhi, Liu Ziming, Liu Shuai /* 输出结果 */

同理,Top(n)表示截取前n条数据。


三、分组查询

在学习之前,我们要做一些准备工作,我们需要创建User对象和包含User对象的集合,作为后面查询和输出的数据源,参见这篇文章C#进阶之LINQ表达式总结完成准备工作。

数据源:

linq002 1 - C#进阶-LINQ表达式之GroupBy分组查询

1、单属性分组查询全部信息

这里我们举一个最简单的例子,根据职业分组,获得每组的集合:

/* C#版本1 /
IEnumerable<IGrouping<string, User>> UserGroupByOccupation = list.GroupBy(s => s.occupation);
/
C#版本2 /
IEnumerable<IGrouping<string, User>> UserGroupByOccupation
= from u in list
group u by u.occupation into n
select n;
/
C#版本3 */
//这里的版本3是版本2的衍生版本,用自定义对象类ListGroupResult替代 IGrouping<string, User>
class ListGroupResult
{
public string Key { get; set; }
public List UserList { get; set; }
}
IIEnumerable UserGroupByOccupation
= from u in list
group u by u.occupation into n
select new ListGroupResult()
{
Key = n.Key, //这个Key是occupation
UserList = n.ToList()
};

根据Occupation分为四组:

GroupBy004 - C#进阶-LINQ表达式之GroupBy分组查询

GroupBy003 - C#进阶-LINQ表达式之GroupBy分组查询

GroupBy002 - C#进阶-LINQ表达式之GroupBy分组查询

GroupBy001 - C#进阶-LINQ表达式之GroupBy分组查询

/* 遍历 输出 /
/适用于C#版本1 和2/
foreach(IGrouping<string, User> u in UserGroupByOccupation)
{
Console.WriteLine(u.Key);
foreach (User user in u)
{
Console.WriteLine(PrintUserObject(user));
}
}
/适用于C#版本3/
foreach(ListGroupResult u in UserGroupByOccupation)
{
Console.WriteLine(u.Key);
foreach (User user in u.UserList)
{
Console.WriteLine(PrintUserObject(user));
}
}
/
输出结果 */
Teacher
{id = 1, name = Zhang Long, age = 38, gender = True, occupation = Teacher}
{id = 3, name = Zhang Shuai, age = 38, gender = False, occupation = Teacher}
Student
{id = 2, name = Zhang Jin, age = 18, gender = False, occupation = Student}
{id = 9, name = Hu Ziming, age = 21, gender = True, occupation = Student}
{id = 10, name = Hu Jin, age = 21, gender = False, occupation = Student}
Doctor
{id = 4, name = Liu Guangzhi, age = 38, gender = False, occupation = Doctor}
{id = 5, name = Liu Ziming, age = 38, gender = True, occupation = Doctor}
{id = 6, name = Liu Shuai, age = 29, gender = False, occupation = Doctor}
Builder
{id = 7, name = Liu Jin, age = 21, gender = True, occupation = Builder}
{id = 8, name = Jiang Long, age = 38, gender = True, occupation = Builder}


2、多属性分组查询全部信息

这次,我们根据职业和性别两个属性分组,获得每组的集合:

/* C#版本1 */
class ListMultiGroupResult
{
public string Occupation { get; set; }
public bool Gender { get; set; }
public List UserList { get; set; }
}
IEnumerable UserGroupByOccupationAndGender
= list.GroupBy(s => new { s.occupation, s.gender })
.Select(g => new ListMultiGroupResult()
{
Occupation = g.Key.occupation,
Gender = g.Key.gender,
UserList = g.ToList()
});

这里根据Occupation和Gender分组后一共分为七组:

/* 遍历 输出 /
/适用于C#版本1/
foreach(ListMultiGroupResult u in UserGroupByOccupationAndGender)
{
Console.WriteLine(u.Occupation + “/” + u.Gender);
foreach (User user in u.UserList)
{
Console.WriteLine(PrintUserObject(user));
}
}
/
输出结果 */
Teacher/True
{id = 1, name = Zhang Long, age = 38, gender = True, occupation = Teacher}
Student/False
{id = 2, name = Zhang Jin, age = 18, gender = False, occupation = Student}
{id = 10, name = Hu Jin, age = 21, gender = False, occupation = Student}
Teacher/False
{id = 3, name = Zhang Shuai, age = 38, gender = False, occupation = Teacher}
Doctor/False
{id = 4, name = Liu Guangzhi, age = 38, gender = False, occupation = Doctor}
{id = 6, name = Liu Shuai, age = 29, gender = False, occupation = Doctor}
Doctor/True
{id = 5, name = Liu Ziming, age = 38, gender = True, occupation = Doctor}
Builder/True
{id = 7, name = Liu Jin, age = 21, gender = True, occupation = Builder}
{id = 8, name = Jiang Long, age = 38, gender = True, occupation = Builder}
Student/True
{id = 9, name = Hu Ziming, age = 21, gender = True, occupation = Student}


3、分组并对各组进行计算

来看一个SQL中常用的场景例子:

/* SQL里的表达: 按照用户职业分组,查出每个分组的人数及各组的年龄最大值、最小值、平均值和总和 */
SELECT occupation,COUNT(id),MAX(age),MIN(age),AVG(age),SUM(age) FROM USER GROUP BY occupation;

/* C#版本1 */
class AgeGroupResult
{
public string Key { get; set; }
public int MaxAge { get; set; }
public int MinAge { get; set; }
public double AvgAge { get; set; }
public int SumAge { get; set; }
}
IEnumerable userList
= from u in list
group u by u.occupation into n
select new AgeGroupResult()
{
Key = n.Key, //这个Key是occupation
MaxAge = n.Max(r => r.age),
MinAge = n.Min(r => r.age),
AvgAge = n.Average(r => r.age),
SumAge = n.Sum(r => r.age),
};

/* 遍历 输出 */
/适用于C#版本1/
foreach (AgeGroupResult u in userList)
{
Console.WriteLine(PrintAgeGroupObject(u));
}

/* 输出结果 */
{Key = Teacher, MaxAge = 38, MinAge = 38, AvgAge = 38, SumAge = 76}
{Key = Student, MaxAge = 21, MinAge = 18, AvgAge = 20, SumAge = 60}
{Key = Doctor, MaxAge = 38, MinAge = 29, AvgAge = 35, SumAge = 105}
{Key = Builder, MaxAge = 38, MinAge = 21, AvgAge = 29.5, SumAge = 59}


四、多表查询

在学习之前,我们要做一些准备工作,我们需要创建User对象和包含User对象的集合,创建Salary对象和包含Salary对象的集合,作为后面查询和输出的数据源,参见这篇文章C#进阶之LINQ表达式总结完成准备工作。

数据源1:

linq002 1 - C#进阶-LINQ表达式之多表查询Ⅰ

数据源2:

Join001 1 - C#进阶-LINQ表达式之多表查询Ⅰ


1、交集 Intersect

如同数学中中的交集,集合[1,2,3]和集合[2,3,4]的交集是[2,3],Linq的交集是两种相同结果类型结果集的重合部分。
比如下面这个例子:

/* SQL里的表达: 求25岁以上且薪水超过17000的用户姓名、职业*/
SELECT name,occupation FROM User WHERE age > 25; /先查询25岁以上的用户姓名、职业/
INTERSECT
SELECT name,occupation FROM Salary WHERE salary > 17000; /再查询薪水超过17000的用户姓名、职业/

/* 在比较两个对象元素之前,我们先重写一个比较对象*/
class CompareUser : IEqualityComparer
{
public bool Equals(User x, User y)
{
if (x.name == y.name && x.occupation.ToLower() == y.occupation.ToLower())
return true;
return false;
}
public int GetHashCode(User obj)
{
return (obj.name+obj.occupation).Length;
}
}
/查询年龄大于25的用户集合,投影存储他们的姓名和职业/
List user_list = list.Where(u => u.age > 25)
.Select(g => new User(){
name = g.name,
occupation = g.occupation
}).ToList();
/查询薪水大于17000的用户集合,投影存储他们的姓名和职业/
List salary_list = salaryList.Where(u => u.salary > 17000)
.Select(g => new User(){
name = g.name,
occupation = g.occupation
}).ToList();
/取上面两个集合的交集为结果集/
List result_list = user_list.Intersect(salary_list, new CompareUser()).ToList();

/* 遍历 输出 /
foreach (User user in user_list)
{
Console.WriteLine(PrintUserObject(user));
}
foreach (User user in salary_list)
{
Console.WriteLine(PrintUserObject(user));
}
foreach (User user in result_list)
{
Console.WriteLine(PrintUserObject(user));
}
/
输出结果 /
/
年龄大于25的用户集合 /
{id = 0, name = Zhang Long, age = 0, gender = False, occupation = Teacher}
{id = 0, name = Zhang Shuai, age = 0, gender = False, occupation = Teacher}
{id = 0, name = Liu Guangzhi, age = 0, gender = False, occupation = Doctor}
{id = 0, name = Liu Ziming, age = 0, gender = False, occupation = Doctor}
{id = 0, name = Liu Shuai, age = 0, gender = False, occupation = Doctor}
{id = 0, name = Jiang Long, age = 0, gender = False, occupation = Builder}
/
薪水高于17000的用户集合 /
{id = 0, name = Liu Shuai, age = 0, gender = False, occupation = Doctor}
/
交集结果集 */
{id = 0, name = Liu Shuai, age = 0, gender = False, occupation = Doctor}


2、并集 Union

如同数学中中的并集,集合[1,2,3]和集合[2,3,4]的交集是[1,2,3,4],Linq的并集是两种相同结果类型结果集的合并集合。
比如下面这个例子:

/* SQL里的表达: 求25岁以上和薪水少于8000的用户姓名、职业*/
SELECT name,occupation FROM User WHERE age > 25; /先查询25岁以上的用户姓名、职业/
UNION
SELECT name,occupation FROM Salary WHERE salary < 8000; /再查询薪水少于8000的用户姓名、职业/

/同样需要上面求交集时的比较对象/
/查询年龄大于25的用户集合,投影存储他们的姓名和职业/
List user_list = list.Where(u => u.age > 25)
.Select(g => new User(){
name = g.name,
occupation = g.occupation
}).ToList();
/查询薪水少于8000的用户集合,投影存储他们的姓名和职业/
List salary_list = salaryList.Where(u => u.salary < 8000)
.Select(g => new User(){
name = g.name,
occupation = g.occupation
}).ToList();
/取上面两个集合的交集为结果集/
List result_list = user_list.Union(salary_list, new CompareUser()).ToList();

/* 遍历 输出 /
foreach (User user in user_list)
{
Console.WriteLine(PrintUserObject(user));
}
foreach (User user in salary_list)
{
Console.WriteLine(PrintUserObject(user));
}
foreach (User user in result_list)
{
Console.WriteLine(PrintUserObject(user));
}
/
输出结果 /
/
年龄大于25的用户集合 /
{id = 0, name = Zhang Long, age = 0, gender = False, occupation = Teacher}
{id = 0, name = Zhang Shuai, age = 0, gender = False, occupation = Teacher}
{id = 0, name = Liu Guangzhi, age = 0, gender = False, occupation = Doctor}
{id = 0, name = Liu Ziming, age = 0, gender = False, occupation = Doctor}
{id = 0, name = Liu Shuai, age = 0, gender = False, occupation = Doctor}
{id = 0, name = Jiang Long, age = 0, gender = False, occupation = Builder}
/
薪水少于8000的用户集合 /
{id = 0, name = Zhang Long, age = 0, gender = False, occupation = Teacher}
{id = 0, name = Zhang Jin, age = 0, gender = False, occupation = Student}
{id = 0, name = Liu Jin, age = 0, gender = False, occupation = Builder}
{id = 0, name = Hu Ziming, age = 0, gender = False, occupation = Student}
{id = 0, name = Hu Jin, age = 0, gender = False, occupation = Student}
/
并集结果集 */
{id = 0, name = Zhang Long, age = 0, gender = False, occupation = Teacher}
{id = 0, name = Zhang Shuai, age = 0, gender = False, occupation = Teacher}
{id = 0, name = Liu Guangzhi, age = 0, gender = False, occupation = Doctor}
{id = 0, name = Liu Ziming, age = 0, gender = False, occupation = Doctor}
{id = 0, name = Liu Shuai, age = 0, gender = False, occupation = Doctor}
{id = 0, name = Jiang Long, age = 0, gender = False, occupation = Builder}
{id = 0, name = Zhang Jin, age = 0, gender = False, occupation = Student}
{id = 0, name = Liu Jin, age = 0, gender = False, occupation = Builder}
{id = 0, name = Hu Ziming, age = 0, gender = False, occupation = Student}
{id = 0, name = Hu Jin, age = 0, gender = False, occupation = Student}


3、全集 Concat

不同于并集(Union)去除了两个集合重复的元素,Concat保留重复的元素。
比如,{1,2,3}和{3,4,5}的Union结果是{1,2,3,4,5},而Concat的结果是{1,2,3,3,4,5}。


4、差集 Except

如同数学中中的差集,集合[1,2,3]和集合[2,3]的交集是[1],代码和交并集类似。

/C#写法/
List result_list = big_list.Except(small_list).ToList()


5、去重 Distinct

如同数学中中的去重,集合[1,2,3]和集合[2,3,4]的去重集是[1],即从集合[1,2,3]中剔除集合[2,3,4]中出现的集合[1,2,3]中的元素,[1,2,3]中剔除[2,3],故结果集是[1]。代码和交并集类似。

/C#写法/
List result_list = big_list.Distinct(small_list).ToList()


6、合并 Zip

Zip函数可以按照元素顺序合并两个集合的元素组成一个装纳新元素的集合,集合[1,2,3]和集合[2,3,4],可以合并成[12,23,34]这种字符串拼接的集合,也可以合并成[{1,2},{2,3},{3,4}]这种新的匿名对象集合。

/C#写法/
//合并为字符串拼接的新字符串集合
IEnumerable unionList = list.Zip(salaryList, (i1, i2) => i1.name + ", " + i2.occupation);
//合并为新的匿名对象集合
var unionList = list.Zip(salaryList, (i1, i2) => new { n = i1.name, m = i2.occupation });


五、Join连接查询

数据源1:

linq002 1 - C#进阶-LINQ表达式之多表查询Ⅱ

数据源2:

Join001 1 - C#进阶-LINQ表达式之多表查询Ⅱ


1、Join连接查询分类

SQL中常见的连接查询有:

  • left join : 左连接,返回左表中所有的记录以及右表中连接字段相等的记录。
  • right join : 右连接,返回右表中所有的记录以及左表中连接字段相等的记录。
  • inner join : 内连接,又叫等值连接,只返回两个表中连接字段相等的行。
  • full join : 外连接,返回两个表中的行:left join + right join。
  • cross join : 结果是笛卡尔积,就是第一个表的行数乘以第二个表的行数。

Linq只有Join这个函数。

Linq中的Join连接查询是通过调换关联表和被关联表的顺序来转换左右连接的方向,通过调整Where和On等条件筛选函数的位置,来改变逻辑,实现更复杂的内连接全连接等功能。

同样,Linq的join方法也有两种写法:

/* C#写法1 <Linq写法>*/
IEnumerable SalaryList =
from u in list
join s in salaryList
on u.id equals s.user_id
select s;

/C#写法2 <Lambda写法>/
IEnumerable SalaryList = list
.Join(
inner: salaryList, /inner: 可以省略/
outerKeySelector: u => u.id, /outerKeySelector: 可以省略/
innerKeySelector: s => s.user_id, /innerKeySelector: 可以省略/
resultSelector: (u, s) => s /resultSelector: 可以省略/
);


2、单条件Join连接查询

如上面两张表,数据表2的user_id是数据表1的外键,对应数据表1的id,可以通过关联查询把两张表不同的属性通过用户一一对应。
我们举个例子,利用关联查询查询表1用户信息和对应在表2的薪资信息:

/* SQL里的表达: 查询所有用户的姓名、年龄、职业、性别、是否在职和薪资*/
SELECT u.id, u.name, u.age, u.occupation, u.gender, s.active, s.salary
FROM
User AS u
LEFT JOIN
Salary AS s
ON u.id = s.user_id;

/* C#写法1*/
IEnumerable UserSalaryList =
from u in list
join s in salaryList on u.id equals s.user_id
select new UserSalary
{
id = u.id,
name = u.name,
age = u.age,
occupation = u.occupation,
gender = u.gender,
active = s.active,
salary = s.salary
};
/C#写法2/
IEnumerable UserSalaryList = list
.Join(salaryList, u => u.id, s => s.user_id, (u, s) => new UserSalary
{
id = u.id,
name = u.name,
age = u.age,
occupation = u.occupation,
gender = u.gender,
active = s.active,
salary = s.salary
});

/* 遍历 输出 */
foreach (UserSalary user in UserSalaryList)
{
Console.WriteLine(PrintUserSalaryObject(user));
}

/* 输出结果 */
{id = 1, name = Zhang Long, age = 38, gender = True, occupation = Teacher, active = True, salary = 7800}
{id = 2, name = Zhang Jin, age = 18, gender = False, occupation = Student, active = True, salary = 1500}
{id = 3, name = Zhang Shuai, age = 38, gender = False, occupation = Teacher, active = False, salary = 8800}
{id = 4, name = Liu Guangzhi, age = 38, gender = False, occupation = Doctor, active = True, salary = 12800}
{id = 5, name = Liu Ziming, age = 38, gender = True, occupation = Doctor, active = True, salary = 13600}
{id = 6, name = Liu Shuai, age = 29, gender = False, occupation = Doctor, active = False, salary = 29000}
{id = 7, name = Liu Jin, age = 21, gender = True, occupation = Builder, active = True, salary = 7000}
{id = 8, name = Jiang Long, age = 38, gender = True, occupation = Builder, active = False, salary = 8500}
{id = 9, name = Hu Ziming, age = 21, gender = True, occupation = Student, active = True, salary = 2100}
{id = 10, name = Hu Jin, age = 21, gender = False, occupation = Student, active = True, salary = 1300}


3、多条件Join连接查询

/* SQL里的表达: 用name和id两个属性关联用户表和薪资表,
查询所有用户中性别是男性且在职的工资信息*/
/* SQL写法1*/
SELECT * FROM User AS u
RIGHT JOIN Salary AS s
ON u.id = s.user_id AND u.name = s.name
AND u.gender = true AND s.active = true;

/* SQL写法2*/
/把筛选条件放到JoinOn后面的Where里可以避免左右连接
带来的半壁空值的困扰,相当于先关联再筛选
/
SELECT * FROM User AS u
RIGHT JOIN Salary AS s
ON u.id = s.user_id AND u.name = s.name
WHERE u.gender = true AND s.active = true;

/* C#写法1*/
/这种写法不推荐,结果集会有null,
推荐关联后取得数据再做筛选,
即把筛选条件写在Join后的结果集处理里
/
IEnumerable JointList = (
from r1 in list
where r1.gender
join r2 in (from r3 in salaryList
where r3.active select r3)
on new
{
ID = r1.id,
r1.name
}
equals new
{
ID = r2.user_id,
r2.name
}
into cls
from c in cls.DefaultIfEmpty()
select c
).ToList();

/C#写法2/
IEnumerable JointList = (
from r1 in list
where r1.gender
join r2 in salaryList
on new
{
ID = r1.id,
r1.name
}
equals new
{
ID = r2.user_id,
r2.name
}
into cls
from c in cls.DefaultIfEmpty()
where c.active
select c
).ToList();

/C#写法3/
IEnumerable JointList = (
from r1 in list
from r2 in salaryList
where
r2.active &&
r1.id == r2.user_id &&
r1.name == r2.name &&
r1.gender
select r2
).ToList();

/C#写法4 <Lambda写法>/
IEnumerable JointList =
list.Where(u => u.gender)
.Join(
salaryList.Where(s => s.active),
u => new { ID = u.id, u.name },
s => new { ID = s.user_id, s.name },
(u, s) => s
);

/C#写法5 <Lambda写法>/
/把方法4对Salary集合的筛选放在整个连接查询的后面,
因为gender是User的专有属性,所以gender的筛选不能
放到内容对象为Salary的结果集后面
/
IEnumerable JointList =
list.Where(u => u.gender)
.Join(
salaryList,
u => new { ID = u.id, u.name },
s => new { ID = s.user_id, s.name },
(u, s) => s
).Where(s => s.active);

/* 遍历 输出 */
foreach (Salary salary in JointList)
{
if(salary != null)
Console.WriteLine(PrintUserSalaryObject(salary));
}

/* 输出结果 */
{id = 1, name = Zhang Long, occupation = Teacher, active = True, salary = 7800}
{id = 5, name = Liu Ziming, occupation = Doctor, active = True, salary = 13600}
{id = 7, name = Liu Jin, occupation = Builder, active = True, salary = 7000}
{id = 9, name = Hu Ziming, occupation = Student, active = True, salary = 2100}


img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

u => new { ID = u.id, u.name },
s => new { ID = s.user_id, s.name },
(u, s) => s
).Where(s => s.active);

/* 遍历 输出 */
foreach (Salary salary in JointList)
{
if(salary != null)
Console.WriteLine(PrintUserSalaryObject(salary));
}

/* 输出结果 */
{id = 1, name = Zhang Long, occupation = Teacher, active = True, salary = 7800}
{id = 5, name = Liu Ziming, occupation = Doctor, active = True, salary = 13600}
{id = 7, name = Liu Jin, occupation = Builder, active = True, salary = 7000}
{id = 9, name = Hu Ziming, occupation = Student, active = True, salary = 2100}


[外链图片转存中…(img-A5a2Wn1k-1715705260534)]
[外链图片转存中…(img-bRDEGy6O-1715705260535)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值