栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > .Net

.Net Linq拓展方法——Join和GroupJoin

.Net 更新时间:发布时间: 百科书网 趣学号

语言集成查询:Language Integrated Query是微软一项很好的技术和工具,可以方便程序员对数据集进行操作。

Linq有两种使用方式,一种是linq子句,一种是拓展方法,二者是一样的,但拓展方法更整洁好用。

扩展方法:使你能够向现有类型“添加”方法(包括你自定义的类型和对象噢),而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但是可以像扩展类型上的实例方法一样进行调用。

System.Linq说明文档

本文主要记录了Linq拓展方法Join和GroupJoin的使用。

三个类表关系如下

【菜单】包含多个【子模块】,【子模块】可以属于多个【菜单】。多对多关系通过【包含】联系关联。【子模块】是一棵树,自身通过属性“父节点”实现自身嵌套。

实现代码如下: 

    /// 
    /// 菜单
    /// 
    public class Menu1
    {
        public int ID { get; set; }
        public string Name { get; set; }
        /// 
        /// 菜单包含模块
        /// 

        [SqlSugar.SugarColumn(IsIgnore = true)]
        public List Models { get; set; }
}

    /// 
    /// 模块
    /// 
    public class Model
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int ParentID { get; set; }
        /// 
        /// 子模块
        /// 
        [SqlSugar.SugarColumn(IsIgnore = true)]
        public ListChildren { get; set; }

    }

    /// 
    /// 菜单模块关系
    /// 
    public class Relation
    {
        public int MenuID { get; set; }

        public int ModelID { get; set; }
        /// 
        /// 模块ID对应模块内容
        /// 

        [SqlSugar.SugarColumn(IsIgnore =true)]
        public Model Model { get; set; }
    }

    public static class Main
    {
        public static void Test()
        {    
            //SqlSugar仓储模式查询数据
            //菜单
            var menuDal = new BaseServices();
            List menus = menuDal.Query().Result;
            //菜单-模块关系
            var menuModelDal = new BaseServices();
            List menuModels = menuModelDal.Query().Result;
            //模块
            var modellDal = new BaseServices();
            //Result是异步方法,ToTree是SqlSugar将结果转化为tree
            List models = modellDal.Queryable().Result.ToTree(it => it.Children, it => it.ParentID, 0);

            //1、将模块与menumodel关联在一起
            var newMenuModels = menuModels.Join
                        (models, p => p.ModelID, q => q.ID, (p, q) => new Relation()
                        {
                            MenuID = p.MenuID,
                            ModelID = p.ModelID,
                            Model = q
                        });
            //2、将菜单和菜单-模块关联在一起
            var newMenu = menus.GroupJoin(newMenuModels, p => p.ID, q => q.MenuID,
                (p, q) => new Menu1()
                {
                    ID = p.ID,

                    Name = p.Name,

                    Models = q.Where(r => r.MenuID == p.ID)
                  .Select(s => s.Model).ToList(),
                }
              ).ToList();
        }

    }

方法详细分析如下: 

Join:基于匹配键对两个序列的元素进行关联。

Join(IEnumerable, IEnumerable, Func, Func, Func)

类型参数

TOuter:第一个序列中的元素的类型。

TInner:第二个序列中的元素的类型。

TKey:键选择器函数返回的键的类型。

TResult:结果元素的类型。

参数

outer:IEnumerable:要联接的第一个序列。

inner:IEnumerable:要与第一个序列联接的序列。

outerKeySelector:Func:用于从第一个序列的每个元素提取联接键的函数。

innerKeySelector:Func:用于从第二个序列的每个元素提取联接键的函数。

resultSelector:Func:用于从两个匹配元素创建结果元素的函数。

返回

IEnumerable:一个 IEnumerable,其中包含通过对两个序列执行内部联接获得的、类型为 TResult 的元素。

使用分析:Join是左连接,函数参数中前四个都好理解,分别是左数据源、右数据源,左数据源的主键和右关联件的外键(第一项this不是参数,是指调用方法的实例对象)。第五项为结果处理,即如何返回指定类型的结果。这是一个Func委托Func,第一个至倒数第二个参数均为输入类型,最后一个为输出类型。所以

Join这个返回结果,就是扔进去一个回调函数,在函数体内调用回调函数,左右数据源的项为参数生成新的结果集。最后将回调的结果生成List后返回出来。(这地方就是给不了解委托的读者的一个简单解释。委托就是事先定义好干什么Delegate(参数、返回类型)和调用位置。然后在外面实现一个Delegate的实例 callback 甩进调用过程中)

 GroupJoin:基于键值等同性将两个序列的元素进行关联,并对结果进行分组。

GroupJoin(IEnumerable, IEnumerable, Func, Func, Func,TResult>, IEqualityComparer)

类型参数

TOuter:第一个序列中的元素的类型。

TInner:第二个序列中的元素的类型。

TKey:键选择器函数返回的键的类型。

TResult:结果元素的类型。

参数

outer:IEnumerable:要联接的第一个序列。

inner:IEnumerable:要与第一个序列联接的序列。

outerKeySelector:Func:用于从第一个序列的每个元素提取联接键的函数。

innerKeySelector:Func:用于从第二个序列的每个元素提取联接键的函数。

resultSelector:Func,TResult>:用于从第一个序列的元素和第二个序列的匹配元素集合中创建结果元素的函数。

comparer:IEqualityComparer:用于对键进行哈希处理和比较的 IEqualityComparer

返回

IEnumerable:一个包含通过对两个序列执行分组联接获得的类型为 TResult 的元素的 IEnumerable

 参数和Join基本类似,但是多了一个分组,就是如何进行分组和将分组结果装进返回结果中。这里我采用了在结果集中通过Where过滤方式生成分组结果。但我感觉既然GroupJoin就应该不是我采用Where方式分组,还有更简单的方式。如果找到了再就更新。

最后测试了一下,采用Linq比自己写Foreach逻辑块提高速度26%,更重要是代码简洁多了。

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/1065961.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号