BlogEngine.Net架构与源代码分析系列part9:开发扩展(上)
此查询里面部分可以被称为相关子查询.当一个子查询引用了外部查询的对象我们可以称它们是相关的-在这个例子中,它引用了d,代表了被枚举的目录. 如果是本地查询, 一个select里面的子查询会引起双延迟执行. 在我们的例子中,目录下的文件不会被选取直到内部foreach表达式被枚举执行.
LINQ to SQL当中的子查询和连接 子查询在LINQ to SQL当中同样可以很好的工作,他们可以被用于SQL风格的连接查询.以下的例子查询客户的名称以及它对应的采购订单: 1: var query =
2:
3: from c in dataContext.Customers 4:
5: select new 6:
7: {
8:
9: c.Name,
10:
11: Purchases =
12:
13: from p in dataContext.Purchases 14:
15: where p.CustomerID == c.ID && p.Price > 1000 16:
17: select new { p.Description, p.Price } 18:
19: };
此查询匹配了来自两个不同集合的对象,可以想象为是”join”.与传统的数据库连接不同的是它并不会将结果集转换为一个扁平的二维数组,而是将关系型数据映射到一个层级数据对象上. 以下是一个利用Customer上的Purchase关联属性的查询,结果与上述的例子一致,但语法则更加简要一点: 1: from c in dataContext.Customers 2:
3: select new 4:
5: {
6:
7: c.Name,
8:
9: Purchases = from p in c.Purchases 10:
11: where p.Price > 1000 12:
13: select new { p.Description, p.Price } 14:
15: };
两个查询都是类似于SQL当中的LEFT OUT JOIN,即我们将选择所有的客户列表,即使他们没有任何的采购订单. 如果要将其改变为INNER JOIN,及那些不包含符合条件采购订单的客户将被排除,要做到这点我们可以在Purchase集合上增加一个过滤条件: 1: from c in dataContext.Customers 2:
3: where c.Purchases.Any (p => p.Price > 1000) 4:
5: select new { 6:
7: c.Name,
8:
9: Purchases =
10:
11: from p in c.Purchases 12:
13: where p.Price > 1000 14:
15: select new { p.Description, p.Price } 16:
17: };
这个查询稍微有点混乱,因为我们编写了两次相同的判定(Price > 1000).通过let语句我们可以去掉这个重复: 1: from c in dataContext.Customers 2:
3: let highValueP = from p in c.Purchases 4:
5: where p.Price > 1000 6:
7: select new { p.Description, p.Price } 8:
9: where highValueP.Any() 10:
11: select new { c.Name, Purchases = highValueP };
这种风格的查询的非常灵活的,例如通过将Any改为Count,我们可以改写此查询去选择那些包含至少两个采购订单的客户: 1: from c in dataContext.Customers 2:
3: let highValueP = from p in c.Purchases 4:
5: where p.Price > 1000 6:
7: select new { p.Description, p.Price } 8:
9: where highValueP.Count() >= 2 10:
11: select new { c.Name, Purchases = highValueP };
|
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |