首页 技术 正文
技术 2022年11月21日
0 收藏 455 点赞 2,209 浏览 3294 个字

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 Categoriesleft join Products on  Categories.Id = Products.CateIdorder 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 常规实践总结或加关注。

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

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,020
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,513
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,359
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,142
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,772
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,850