继续介绍一些复杂的linq。
groupjoin 这个函数:
有department
public class Deployment { public string Id { get; set; } public Deployment(string id) { Id = id; } }
有Employee:
public class Employee { public string DepartmentId { get; set; } public string Name { get; set; } public Employee(string name, string deploymentId) { Name = name; DepartmentId = deploymentId; } }
现在要实现Deployment和Employee,一对多的关系:
List<Deployment> a = new List<Deployment>() { new Deployment("1"), new Deployment("2"), }; List<Employee> e = new List<Employee>() { new Employee("张三","1"), new Employee("李四","1"), new Employee("王五","2"), };
如果我们使用join的话,那么就是:
Deployment("1") Employee("张三","1") Deployment("1") Employee("李四","1") Deployment("2") Employee("王五","2")
就是这种平铺的关系。然后再使用group by。
Deployment("1") Employee("张三","1") Employee("李四","1") Deployment("2") Employee("王五","2")
现在有一个函数可以直接到达这种效果,那么就是groupjoin:
static void Main(string[] args) { List<Deployment> a = new List<Deployment>() { new Deployment("1"), new Deployment("2"), }; List<Employee> e = new List<Employee>() { new Employee("张三","1"), new Employee("李四","1"), new Employee("王五","2"), }; var c = a.GroupJoin(e, deployment => deployment.Id, employee => employee.DepartmentId, (department, exployees) =>(department.Id, exployees) ); Console.ReadKey(); }
其实可以看到这个exployees,最终运行时是一个Igroup类型,这和join还有group by不同之处。
然后这里写一下join和group by的。
static void Main(string[] args) { List<Deployment> a = new List<Deployment>() { new Deployment("1"), new Deployment("2"), new Deployment("3") }; List<Employee> e = new List<Employee>() { new Employee("张三","1"), new Employee("李四","1"), new Employee("王五","2"), }; var f = from a1 in a join e1 in e on a1.Id equals e1.DepartmentId into temps from tt in temps.DefaultIfEmpty() select (a1.Id, (a1.Id, tt)); var d = from f1 in f group f1 by f1.Id; Console.ReadKey(); }
这里要说明的就是groupjoin 是一个左连接。
上面用的是linq的查询表达式,因为join 方法其实是inner join。
对于表达式来说其实最终还是生成方法而已,IL 来说没有表达式这回事,可以理解为c#的语法糖。
看下如果上述的linq用方法来怎么写吧。
其实还是用的是groupjoin:
这里可以看出,其实上述这个linq表达式就是groupjoin 然后用selectmany拆开,然后在用group再聚合。。
如果你只需要获取每个部门下的员工,用groupjoin 效率是更高的。
当然这里主要是说明linq 的表达式最终都是方法,语法糖而已。表达式是为了让我们更加清晰的去描述。
如果写一些复杂的linq,那么最好去用linq表达式。通过如果是groupjoin 就能实现的,就没必要去使用,这可能效率更低。
这里提到了selectmany,那么就讲述一下selectmany。 group by 是聚合,那么selectmany就是拆分。
public class BasketballTeam { public string Name { get; set; } public string[] TeamMember; } static void Main(string[] args) { List<BasketballTeam> list = new List<BasketballTeam>(); BasketballTeam basketballTeam = new BasketballTeam(); basketballTeam.Name = "无敌球队"; basketballTeam.TeamMember = new string[] { "张三", "李四", "王五" }; BasketballTeam basketballTeam1 = new BasketballTeam(); basketballTeam1.Name = "小新球团"; basketballTeam1.TeamMember = new string[] { "张嘛子", "李老帽", "王七三" }; list.Add(basketballTeam); list.Add(basketballTeam1); var a = list.SelectMany(u=> u.TeamMember, (u,s)=> u.Name + " " + s); foreach (var item in a) { Console.WriteLine(item); } Console.ReadKey(); }
selectMany 就是用来处理集合的集合的,是一个展开过程。
上面代码是遍历一组球队的全部成员。
有兴趣可以去看下代码,其实都能猜到,就是两个foreach 循环的封装。
下面介绍一下c# 匿名类型对linq使用:
如果临时使用,那么可以使用匿名类型。
匿名类型其实不是说真的匿名,其实是编译的时候会生成一个类。
如果两者完全一样,那么将会生成一个类,如果只要有一点结构不同,那么会生成两个类。
因为上面一致,所以赋值。
顺序不一致,依然生成不同的类。
不过现在元组替代了匿名类型,因为元组在方法外部也可以使用。
然后值得注意的是匿名类型是引用类型,而元组是值类型,如果经常拷贝且内存超过128位就用匿名,否则就是元组。
其实不用纠结元组和匿名,就是元组的功能比匿名强,但是因为元组是值类型,如果经常赋值拷贝的话那么肯定是引用类型更好,所以匿名类型这时候才是用武之地。
标签:c++,icode9,函数,swap,语言,C语言,代码,构建,google 来源:
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。