LINQ 常规实践总结
1.Linq 执行多列排序
OrderBy的意义是按照指定顺序排序,连续两次OrderBy,后面一个有可能会打乱前面一个的排序顺序,可能与预期不符。
要实现sql中的order by word,name类似效果; LINQ 有ThenBy可以紧接使用, ThenBy记住原本排序的值,然后再排其他值, 正因如此,ThenBy是针对IOrderEnumerable 进行调用的。
2. Linq主外键连接查询
group join操作符常用于返回‘主键对象-外键对象集合’的查询,例如‘产品类别-此类别下所有的产品’的模式。
// 查询语法
var query =
from c in db.Categories
join p in db.Products on c.CategoryID equals p.CategoryID into r
select new
{
c.CategoryName,
Products = r
};
// 方法语法
var q =
db.Categories
.GroupJoin
(
db.Products,
c => c.CategoryID,
p => p.CategoryID,
(c, p) => new
{
c.CategoryName,
Products = p
}
);
这样就可以结合 DefaultIfEmpty 理解 left outer join的linq写法。
group join生成的sql接近于:
select Categories.*, Products.* from Categories left join Products on Categories.Id = Products.CateId order by Categories.Id // group join 有点类似于 left join 数据膨胀的效果
https://docs.microsoft.com/en-us/dotnet/csharp/linq/perform-grouped-joins
3.linq2sql 指定形成sql左右连接
linq2sql join语法默认得到的是inner join
Model1Container model = new Model1Container();
//内连接
var query = from s in model.Student
join c in model.Course on s.CourseCno equals c.Cno
select new
{
ClassID = s.CourseCno,
ClassName = c.Cname,
Student = new
{
Name = s.Sname,
ID = s.Sno
}
};
foreach (var item in query)
{
Response.Write("ClassID:" + item.ClassID + "ClassName:" + item.ClassName + "Name:" + item.Student.Name);
}
在sql profile里面监控到与上面Linq2sql 对应的sql是
SELECT [t0].[CourseCno] AS [ClassID], [t1].[Cname] AS [ClassName], [t0].[Sname] AS [Name], [t0].[Sno] AS [ID] FROM [Student] AS [t0] INNER JOIN [Course] AS [t1] ON [t0].[CourseCno] = [t1].[Cno] WHERE [t1].[Cno] = @p0
linq2sql 左连接
Model1Container model = new Model1Container();
var query = from s in model.Student
join c in model.Course on s.CourseCno equals c.Cno into gc
from gci in gc.DefaultIfEmpty()
select new
{
ClassID = s.CourseCno,
ClassName = gci ==null ?String.Empty: gci.Cname,
Student = new
{
Name = s.Sname,
ID = s.Sno
}
};
//Outer join时必须将join后的表into到一个新的变量gc中,然后要用gc.DefaultIfEmpty()表示外连接(没有匹配的记录字段设为NULL)
foreach (var item in query)
{
Response.Write("ClassID:" + item.ClassID + "ClassName:" + item.ClassName + "Name:" + item.Student.Name);
}
// 上例中使用了DefaultIfEmpty操作符,它能够为Empty序列(注意是Empty序列而不是Null序列)返回一个默认元素序列,DefaultIfEmpty使用了泛型中的default关键字。
gc.DefaultIfEmpty(new Course { Cname = "",Cperiod="" } ) //设置为空时的默认值
与以上Linq2sql对应的sql 是
SELECT [t0].[CourseCno] AS [ClassID], [t1].[Cname] AS [ClassName], [t0].[Sname] AS [Name], [t0].[Sno] AS [ID] FROM [Student] AS [t0] LEFT OUTER JOIN [Course] AS [t1] ON [t0].[CourseCno] = [t1].[Cno]
https://docs.microsoft.com/en-us/dotnet/csharp/linq/perform-left-outer-joins
4. 忽略Linq 检索某元素异常
在日常Linq实践中,按照某种预期写定的Linq, 在执行检索时某些元素会爆出异常,导致整个检索失败;如果我们能容忍某些元素的异常,继续完成整个Linq检索,可以写一个扩展方法,忽略报错元素。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Enumerable {
public static class EnumerableExtension {
/// <summary>
/// 在IEnumerable<T> 循环或者变为内存序列之前 忽略掉序列中存在的元素异常
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="values"></param>
/// <returns></returns>
public static IEnumerable<T> SkipException<T> (this IEnumerable<T> values) {
using(var enumerator = values.GetEnumerator()) {
var next = true;
while(next) {
try{
// 如果枚举器成功推进到下一个元素,MoveNext为true;枚举数越过集合结尾,则为false,也就是说返回值只确定后续是否有值
next = enumerator.MoveNext();
} catch{
// catch到异常,忽略当前元素,继续循环
LogHelper.Write("cause exception", LogHelper.LogMessageType.Error);
continue;
}
// yield 返回枚举器指向的当前元素
if(next)
yield return enumerator.Current;
}
}
}
}
}
这个扩展方法的思路是 重写foreach语法糖的默认逻辑:
能够使用foreach语法的序列必定实现IEnumerable接口,此处我们重写了该接口的默认迭代器使用方式。
感谢您的认真阅读,如有问题请大胆斧正,如果您觉得本文对你有用,不妨右下角点个
或加关注。
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置注明本文的作者及原文链接,否则保留追究法律责任的权利。
LINQ 常规实践总结的更多相关文章
- 从linq的一次优化实践看group by+Min/Max()处理数据后需要额外的其他列问题
问题简化如下: 假设有第三方的表结构如下(可能会出现完全相同的重复数据): 1.写SQL语句,查询每个学生的,userid.最高分.最高分的科目.最高分的考点.最低分.最低分科目.最低分考点(分数相同 ...
- C# Linq排序
今天在家看了一下linq,实践了一下书中代码,发现排序和查重的先后顺序太重要了. using System; using System.Collections.Generic; using Syste ...
- NoSQL注入的分析和缓解
本文要点介绍: 1.了解针对NoSQL的新的安全漏洞 2.五类NoSQL攻击手段,比如重言式.联合查询.JavaScript 注入.背负式查询(Piggybacked queries),以及跨域违规 ...
- 使用 Markdown 写技术博客,踩过的 6个坑
目录 Markdown 特性 Markdown 简介 常用语法 为什么流行 设计哲学 工具支持 版本演进 标准化之路 踩过了坑 平台帮助文档 语法差异 显示效果 我的最佳实践 摘要:本文记录我在使用 ...
- C#两大知名Redis客户端连接哨兵集群的姿势
前言 前面利用<Docker-Compose搭建Redis高可用哨兵集群>, 我们的思路是将Redis.Sentinel.Redis Client App链接到同一个网桥网络,这个网桥内的 ...
- C++ Primer 学习笔记_45_STL实践与分析(19)--建筑常规算法
STL实践与分析 --泛型算法的结构 引言: 正如全部的容器都建立在一致的设计模式上一样,算法也具有共同的设计基础. 算法最主要的性质是须要使用的迭代器种类.全部算法都指定了它的每一个迭代器形參可使用 ...
- C# 当中 LINQ 的常规用法(Lambda 方式)
仅以本篇博文记录 LINQ 相关操作的基本知识,原型参考自 MSDN 相关知识,中间加以自己的理解与 DEMO. 1. IEnuemrable<T>.Select() Select 方法比 ...
- Yii2后台管理系统常规单据模块最佳实践
后台管理系统的常规单据通常包括数据,页面,功能:其中数据,页面,功能又可以细分如下: 分类 二级分类 主要内容 注意事项 例如 数据 数据库迁移脚本 用于数据表生成及转态回滚 1.是否需要增 ...
- Linq To Entity学习实践
public class CustomDataContext<TEntity> : System.Data.Linq.DataContext where TEntity : class,n ...
随机推荐
- Spring Security Oauth2 permitAll()方法小记
黄鼠狼在养鸡场山崖边立了块碑,写道:"不勇敢地飞下去,你怎么知道自己原来是一只搏击长空的鹰?!" 从此以后 黄鼠狼每天都能在崖底吃到那些摔死的鸡! 前言 上周五有网友问道,在使用s ...
- python一键刷屏
#当按键q的时候,自动输入 "大家好!"并回车键发送! from pynput import keyboard from pynput.keyboard import Key, C ...
- Ubuntu基础教程——安装谷歌Chrome浏览器
对于刚刚开始使用Ubuntu并想安装谷歌Chrome浏览器的新用户来说,本文所介绍的方法是最快捷的.在Ubuntu上安装谷歌Chrome的方法有很多.一些用户喜欢直接在 谷歌Chrome下载页面 获得 ...
- codeForces 472D 最小生成树
题目大意:给出一个图中点的两两距离,问是否是一棵树,若是,求出平均边权最大的点 prim最小生成树,若原图是树,则最小生成树的距离就是原距离.否则不是. 搞出来树了,第二问随便dfs就好了. #inc ...
- (1)STM32使用HAL库操作GPIO
一 初始化GPIO 使用HAL库的优点在于不用手动添加初始化的代码了,CubeMX会根据软件设置自动生成. 自动生成的HAL库GPIO初始化代码: static void MX_GPIO_Init( ...
- STM32基于固件库新建MDK工程模板(精简版)
上个博文理论讲解的东西太多,太复杂,这里把所有步骤全部贴出 1.新建一个工程文件夹LED 2.LED文件夹下建立如下文件夹 3.Project –>New Uvision Project 到US ...
- BZOJ1500 [NOI2005]维修数列-fhq_Treap
题面见这里 反正是道平衡树,就拿 fhq_Treap 写了写... 这道题思路基本是围绕“用 Treap 维护中序遍历” 和 中序遍历的性质 来进行的操作 所以就可以类比线段树进行一些操作 1. 建树 ...
- eclipse使用Git基本流程
1.安装GIT 2.Git的使用 ①下载代码到eclipse(右键导入工程) ②提交代码到本地(commit) ③更新代码到本地(pull) ④当本地出现冲突时,解决冲突,没有冲突当然就最好啦 ⑤提交 ...
- shell脚本中cd命令无效
对于一段包含cd 命令的shell脚本(test.sh): #!/bin/bash cd .. mkdir ./test 运行: sh ./test.sh 脚本运行时无法在上级目录建立test文件 此 ...
- 循环神经网络之LSTM和GRU
看了一些LSTM的博客,都推荐看colah写的博客<Understanding LSTM Networks> 来学习LSTM,我也找来看了,写得还是比较好懂的,它把LSTM的工作流程从输入 ...