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接口,此处我们重写了该接口的默认迭代器使用方式。

作者:Julian_酱

感谢您的认真阅读,如有问题请大胆斧正,如果您觉得本文对你有用,不妨右下角点个或加关注。

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置注明本文的作者及原文链接,否则保留追究法律责任的权利。

LINQ 常规实践总结的更多相关文章

  1. 从linq的一次优化实践看group by+Min/Max()处理数据后需要额外的其他列问题

    问题简化如下: 假设有第三方的表结构如下(可能会出现完全相同的重复数据): 1.写SQL语句,查询每个学生的,userid.最高分.最高分的科目.最高分的考点.最低分.最低分科目.最低分考点(分数相同 ...

  2. C# Linq排序

    今天在家看了一下linq,实践了一下书中代码,发现排序和查重的先后顺序太重要了. using System; using System.Collections.Generic; using Syste ...

  3. NoSQL注入的分析和缓解

    本文要点介绍: 1.了解针对NoSQL的新的安全漏洞 2.五类NoSQL攻击手段,比如重言式.联合查询.JavaScript 注入.背负式查询(Piggybacked queries),以及跨域违规 ...

  4. 使用 Markdown 写技术博客,踩过的 6个坑

    目录 Markdown 特性 Markdown 简介 常用语法 为什么流行 设计哲学 工具支持 版本演进 标准化之路 踩过了坑 平台帮助文档 语法差异 显示效果 我的最佳实践 摘要:本文记录我在使用 ...

  5. C#两大知名Redis客户端连接哨兵集群的姿势

    前言 前面利用<Docker-Compose搭建Redis高可用哨兵集群>, 我们的思路是将Redis.Sentinel.Redis Client App链接到同一个网桥网络,这个网桥内的 ...

  6. C++ Primer 学习笔记_45_STL实践与分析(19)--建筑常规算法

    STL实践与分析 --泛型算法的结构 引言: 正如全部的容器都建立在一致的设计模式上一样,算法也具有共同的设计基础. 算法最主要的性质是须要使用的迭代器种类.全部算法都指定了它的每一个迭代器形參可使用 ...

  7. C# 当中 LINQ 的常规用法(Lambda 方式)

    仅以本篇博文记录 LINQ 相关操作的基本知识,原型参考自 MSDN 相关知识,中间加以自己的理解与 DEMO. 1. IEnuemrable<T>.Select() Select 方法比 ...

  8. Yii2后台管理系统常规单据模块最佳实践

    后台管理系统的常规单据通常包括数据,页面,功能:其中数据,页面,功能又可以细分如下: 分类  二级分类  主要内容  注意事项  例如 数据 数据库迁移脚本  用于数据表生成及转态回滚 1.是否需要增 ...

  9. Linq To Entity学习实践

    public class CustomDataContext<TEntity> : System.Data.Linq.DataContext where TEntity : class,n ...

随机推荐

  1. 过滤emoji表情符

    1.使用正则匹配 public  function remove_emoji($text){        return preg_replace('/([0-9|#][\x{20E3}])|[\x{ ...

  2. Linux用户和组管理,添加修改用户,添加修改组,加入组,移除组

    1.安全介绍3A Authentication: 认证,用户名和对应口令 Authorization: 授权,不同用户权限不同 Accouting/Audition: 审计 2. 所属者和所属组 us ...

  3. [TJOI2015] 棋盘

    Description 为了提高智商,ZJY去新世界旅游了.可是旅游过后的ZJY杯具的发现要打开通往原来世界的门,必须要解开门上面画的谜题.谜题是这样的:有个\(n\)行\(m\)列的棋盘,棋盘上可以 ...

  4. mac上如何解压和压缩rar文件

    许多喜欢mac的人都知道,这个os没有像win上winRAR或者hao123解压等类似软件,对于文件的压缩和解压很不方便,在下载rar的文件包之后就会束手无策,很是尴尬至极,为了避免这种情况,自己动手 ...

  5. Golang中使用lua进行扩展

    前言 最近在项目中需要使用lua进行扩展,发现github上有一个用golang编写的lua虚拟机,名字叫做gopher-lua.使用后发现还不错,借此分享给大家. 数据类型 lua中的数据类型与go ...

  6. 【游戏开发】Excel表格批量转换成lua的转表工具

    一.简介 在上篇博客<[游戏开发]Excel表格批量转换成CSV的小工具> 中,我们介绍了如何将策划提供的Excel表格转换为轻便的CSV文件供开发人员使用.实际在Unity开发中,很多游 ...

  7. 虚拟机console基础环境部署——系统基础环境

    1. 概述2. 工具类安装2.1 安装vim2.2 安装tree2.3 安装expect2.4 安装lsof3. 编译环境类安装 1. 概述 本系列博客是在最小化安装CentOS6.5的基础上,通过配 ...

  8. Matlab实现画柱状图坐标标签旋转

    引言: 在用matlab画柱状图或者其他图的时候,你是否碰到下图这种情况: 乍一看这个柱状图画的有馍有洋的,but,仔细一看你会发现,横坐标标签如果再长一点就不好看啦,甚至会重叠,就像这样: 这样的图 ...

  9. Java基础-方法重载和方法重写的区别

    什么是java方法重载 (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现. (2)  ...

  10. ruby整理

    参考博客:https://www.cnblogs.com/felixzh/p/8081622.html 官网地址 https://rvm.io/rvm/install 一.前提  centos6.8下 ...