文章目录

  • 前言
  • 1.导航查询用法 (关键字:Includes)
    • 1.1 一对一
    • 1.2 一对多
      • 1.2.1 简单用法
      • 1.2.2 对主主对象进行过滤
      • 1.2.3 对子对象进行排序和过滤
      • 1.2.4 子表加Select
      • 1.2.5 主表加Select
    • 1.3 多对多
      • 1.3.1 简单用法
      • 1.3.2 子对象的过滤和排序
      • 1.3.3 主对象过滤
    • 1.4 手动
    • 1.5 多级导航
      • 1.5.1 三层以下的写法
      • 1.5.2 三层以上的写法
    • 1.6 大数据导航
  • 2.内存对象导航 (关键字:SetContext)
    • 2.1 实现两层
    • 2.2 实现无线层

前言

导航查询特点:

  • 主要处理主对象里面有子对象这种层级关系查询
  • 只需要配置特性和主键即可,不需要外键

1.导航查询用法 (关键字:Includes)

1.1 一对一

用到的实体类:

public class StudentA{[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]public int StudentId { get; set; }public string Name { get; set; }public int SchoolId { get; set; }//新版本修改了命名[Navigate(NavigateType.OneToOne, nameof(SchoolId))]//一一 SchoolId是StudentA类里面的public SchoolA SchoolA { get; set; } //不能赋值只能是null}public class SchoolA{[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]public int SchoolId { get; set; }public string SchoolName { get; set; }}

代码:

List<StudentA> list = db.Queryable<StudentA>().Includes(it => it.SchoolA).ToList();string jsonStr1 = JsonConvert.SerializeObject(list);
string Jsonstr2 = db.Utilities.SerializeObject(list);   //sugar提供的序列化方法//转Json后 将内容粘贴到 https://www.json.cn/ 解析查看数据格式

1.2 一对多

用到的实体类:

public class StudentB{[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]public int StudentId { get; set; }public string Name { get; set; }public int SchoolId { get; set; }[Navigate(NavigateType.OneToMany, nameof(BookB.studenId))]  //BookB表中的studenIdpublic List<BookB> Books { get; set; }  //注意禁止给Books手动赋值}public class BookB{[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]public int BookId { get; set; }public string Name { get; set; }public int studenId { get; set; }}
1.2.1 简单用法

注意:

  • 简单写法 .Includes(it => it.Books.ToList()) 中的 ToList() 可以省略
List<StudentB> list1 = db.Queryable<StudentB>().Includes(it => it.Books).ToList();string jsonStr1 = JsonConvert.SerializeObject(list);
string Jsonstr2 = db.Utilities.SerializeObject(list);    //sugar提供的序列化方法//转Json后 将内容粘贴到 https://www.json.cn/ 解析查看数据格式
1.2.2 对主主对象进行过滤

注意:

  • 支持Any Count,对主对象进行过滤
  • Any 只支持一个层级,第二层级目前不支持
List<StudentB> list = db.Queryable<StudentB>().Includes(it => it.Books).Where(it => it.Name.Equals("B")).ToList();
//提前对主对象进行 条件筛选过滤
List<StudentB> list = db.Queryable<StudentB>().Includes(it => it.Books).Where(it => it.Books.Any(x=>x.Name.Equals("三国"))).ToList();
1.2.3 对子对象进行排序和过滤

注意:

  • Includes 中结尾的 ToList() 方法一定不要少了
  • 否则会报错 “need is ToList()”
List<StudentB> list = db.Queryable<StudentB>().Includes(it => it.Books.Where(b => b.BookId > 3).OrderByDescending(b => b.BookId).ToList()).ToList();
1.2.4 子表加Select

注意:

  • 子表 studenId 是必有字段,剩下字段看 Select 投影了哪个字段,就会在sql查询中显示哪个字段
var list2 = db.Queryable<StudentB>().Includes(it => it.Books.Select(z => new BookB() { BookId = z.BookId }).ToList()).ToList();// SELECT `BookId` AS `BookId` ,`studenId` FROM `BookB`  WHERE   `studenId` IN (1,2,3,4)
var list2 = db.Queryable<StudentB>().Includes(it => it.Books.Select(z => new BookB() { Name = z.Name }).ToList()).ToList();// SELECT `Name` AS `Name` ,`studenId` FROM `BookB`  WHERE   `studenId` IN(1, 2, 3, 4)
1.2.5 主表加Select
var list = db.Queryable<StudentB>().Includes(x => x.Books.ToList()).ToList(it => new{AAA = it.StudentId,BBB = it.Name,CCC = it.Books});string Jsonstr = db.Utilities.SerializeObject(list);
//转Json后 将内容粘贴到 https://www.json.cn/ 解析查看数据格式

1.3 多对多

用到的实体类:

public class ABMapping1
{[SugarColumn(IsPrimaryKey = true)]  //中间表可以不是主键public int AId { get; set; }[SugarColumn(IsPrimaryKey = true)]  //中间表可以不是主键public int BId { get; set; }
}public class A1
{[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]public int Id { get; set; }public string Name { get; set; }[Navigate(typeof(ABMapping1), nameof(ABMapping1.AId), nameof(ABMapping1.BId))]  //注意顺序public List<B1> BList { get; set; }
}public class B1
{[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]public int Id { get; set; }public string Name { get; set; }[Navigat(typeof(ABMapping1), nameof(ABMapping1.BId), nameof(ABMapping1.AId))]   //注意顺序public List<A1> AList { get; set; }
}
1.3.1 简单用法

直接填充子对象B集合,前提是配置好特性

List<A1> list = db.Queryable<A1>().Includes(x => x.BList).ToList();
string Jsonstr = db.Utilities.SerializeObject(list);
1.3.2 子对象的过滤和排序

支持 WhereIF

List<A1> list = db.Queryable<A1>().Includes(it => it.BList.Where(x=>x.Id>3).ToList()).ToList();
string Jsonstr = db.Utilities.SerializeObject(list);
1.3.3 主对象过滤
List<A1> list = db.Queryable<A1>().Includes(a1 => a1.BList).Where(a2 => a2.BList.Any(b => b.Id>2)).ToList();string Jsonstr = db.Utilities.SerializeObject(list);

1.4 手动

用到的实体类:

public class StudentC{[SugarColumn(IsPrimaryKey = true)]public int StudentId { get; set; }public string Name { get; set; }[Navigate(NavigateType.Dynamic, null)] //自定义关系映射public List<BookB> Books { get; set; }}

代码:

List<StudentC> list = db.Queryable<StudentC>().Includes(it => it.Books.MappingField(z => z.studenId, () => it.StudentId).ToList()).ToList();string Jsonstr = db.Utilities.SerializeObject(list);

1.5 多级导航

1.5.1 三层以下的写法

注意:

  • 一对多 多对多 一对多 只要配好了都可以多层级使用

用到的实体类:

public class StudentB{[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]public int StudentId { get; set; }public string Name { get; set; }public int SchoolId { get; set; }[Navigate(NavigateType.OneToOne, nameof(SchoolId))]//一对一public SchoolB SchoolB { get; set; }[Navigate(NavigateType.OneToMany, nameof(BookB.studenId))]//BookB表中的studenId 一对多public List<BookB> Books { get; set; }//注意禁止给Books手动赋值}public class SchoolB{[SugarColumn(IsPrimaryKey = true)]public int SchoolId { get; set; }public string SchoolName { get; set; }[Navigate(NavigateType.OneToMany, nameof(RoomB.SchoolId))]//一对多public List<RoomB> RoomList { get; set; }}public class RoomB{[SugarColumn(IsPrimaryKey = true)]public int RoomId { get; set; }public string RoomName { get; set; }public int SchoolId { get; set; }}public class BookB{[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]public int BookId { get; set; }public string Name { get; set; }public int studenId { get; set; }}

代码:

var list = db.Queryable<StudentB>().Includes(st => st.Books)//一级.Includes(st => st.SchoolB, sch => sch.RoomList)// 一级 + 两级.ToList();string Jsonstr = db.Utilities.SerializeObject(list);
1.5.2 三层以上的写法

注意:

  • 超过3个层级需要.AsNavQueryable()
  • 缺点VS提示会消失,直接写不要在乎意提示不出来,VS关掉在开就行了,只要不改这个代码提示就不会有问题
  • 示例: db.Queryable().AsNavQueryable().Includes(it=>it.1,it=>it.2,it=>it.3,it=>it.4,it=>it.5…)
  • .AsNavQueryable()能不用尽量不要用,正常Includes(+3)重载完全够用了

用到的实体类:

    //省份public class Province{[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]public int Pid { get; set; }public string Pname { get; set; }[Navigate(NavigateType.OneToMany, nameof(City.pid))]public List<City> cityList { get; set; }}//市级public class City{[SugarColumn(IsPrimaryKey = true)]public int Cid { get; set; }public string Cname { get; set; }[Navigate(NavigateType.OneToMany, nameof(District.cid))]public List<District> districtList { get; set; }public int pid { get; set; }}//区级public class District{[SugarColumn(IsPrimaryKey = true)]public int Did { get; set; }public string Dname { get; set; }[Navigate(NavigateType.OneToMany, nameof(Town.did))]public List<Town> townList { get; set; }public int cid { get; set; }}//镇public class Town{[SugarColumn(IsPrimaryKey = true)]public int Tid { get; set; }public string Tname { get; set; }[Navigate(NavigateType.OneToMany, nameof(Village.tid))]public List<Village> villageList { get; set; }public int did { get; set; }}//村public class Village{[SugarColumn(IsPrimaryKey = true)]public int Vid { get; set; }public string Vname { get; set; }public int tid { get; set; }}

插入数据:

INSERT INTO `province` VALUES (1, '山东省');INSERT INTO `city` VALUES (1, '烟台市', 1);
INSERT INTO `city` VALUES (2, '青岛市', 1);
INSERT INTO `city` VALUES (3, '威海市', 1);INSERT INTO `district` VALUES (1, '开发区', 1);
INSERT INTO `district` VALUES (2, '莱山区', 1);
INSERT INTO `district` VALUES (3, '崂山区', 2);INSERT INTO `town` VALUES (1, '大新店镇', 1);
INSERT INTO `town` VALUES (2, '刘家沟镇', 1);
INSERT INTO `town` VALUES (3, '北沟镇', 1);
INSERT INTO `town` VALUES (4, '解甲庄', 2);INSERT INTO `village` VALUES (1, '大呼家村', 1);
INSERT INTO `village` VALUES (2, '回家村', 1);
INSERT INTO `village` VALUES (3, '刘家沟村', 2);
INSERT INTO `village` VALUES (4, '安乡刘家村', 2);
INSERT INTO `village` VALUES (5, '北沟一村', 3);
INSERT INTO `village` VALUES (6, '北沟二村', 3);

代码:

//普通查询,三层var list1 = db.Queryable<Province>().Includes(p => p.cityList, c => c.districtList, d => d.townList).ToList();
string Jsonstr1 = db.Utilities.SerializeObject(list1);//三层以上
var list2 = db.Queryable<Province>().AsNavQueryable().Includes(p => p.cityList, c => c.districtList, d => d.townList, t => t.villageList).ToList();string Jsonstr2 = db.Utilities.SerializeObject(list2);

1.6 大数据导航

暂时没有可测试的环境
文档参考:分批处理

2.内存对象导航 (关键字:SetContext)

  • 手动映射适合没有主键或者复杂的一些操作

用到的实体类:

    public class StudentX{[SugarColumn(IsPrimaryKey = true)]public int StudentId { get; set; }public string Name { get; set; }public int SchoolId { get; set; }[SugarColumn(IsIgnore = true)]public SchoolX SchoolX { get; set; }}public class SchoolX{[SugarColumn(IsPrimaryKey = true)]public int SchoolId { get; set; }public string SchoolName { get; set; }[SugarColumn(IsIgnore = true)]public List<RoomX> RoomList { get; set; }[SugarColumn(IsIgnore = true)]public List<TeacherX> TeacherList { get; set; }}public class TeacherX{[SugarColumn(IsPrimaryKey = true)]public int Id { get; set; }public int SchoolId { get; set; }public string Name { get; set; }}public class RoomX{[SugarColumn(IsPrimaryKey = true)]public int RoomId { get; set; }public string RoomName { get; set; }public int SchoolId { get; set; }}

插入数据:

            db.Insertable(new RoomX() { RoomId = 1, RoomName = "北大001室", SchoolId = 1 }).ExecuteCommand();db.Insertable(new RoomX() { RoomId = 2, RoomName = "北大002室", SchoolId = 1 }).ExecuteCommand();db.Insertable(new RoomX() { RoomId = 3, RoomName = "北大003室", SchoolId = 1 }).ExecuteCommand();db.Insertable(new RoomX() { RoomId = 4, RoomName = "清华001厅", SchoolId = 2 }).ExecuteCommand();db.Insertable(new RoomX() { RoomId = 5, RoomName = "清华002厅", SchoolId = 2 }).ExecuteCommand();db.Insertable(new RoomX() { RoomId = 6, RoomName = "清华003厅", SchoolId = 2 }).ExecuteCommand();db.Insertable(new SchoolX() { SchoolId = 1, SchoolName = "北大" }).ExecuteCommand();db.Insertable(new SchoolX() { SchoolId = 2, SchoolName = "清华" }).ExecuteCommand();db.Insertable(new StudentX() { StudentId = 1, SchoolId = 1, Name = "北大jack" }).ExecuteCommand();db.Insertable(new StudentX() { StudentId = 2, SchoolId = 1, Name = "北大tom" }).ExecuteCommand();db.Insertable(new StudentX() { StudentId = 3, SchoolId = 2, Name = "清华jack" }).ExecuteCommand();db.Insertable(new StudentX() { StudentId = 4, SchoolId = 2, Name = "清华tom" }).ExecuteCommand();db.Insertable(new TeacherX() { SchoolId = 1, Id = 1, Name = "北大老师01" }).ExecuteCommand();db.Insertable(new TeacherX() { SchoolId = 1, Id = 2, Name = "北大老师02" }).ExecuteCommand();db.Insertable(new TeacherX() { SchoolId = 2, Id = 3, Name = "清华老师01" }).ExecuteCommand();db.Insertable(new TeacherX() { SchoolId = 2, Id = 4, Name = "清华老师02" }).ExecuteCommand();

2.1 实现两层

注意:

  • 结构:StudentX → SchoolX
  • 如果没有SetContext那么这个查询将会循环
  • db.ConextId外面和里面需要是同一个
var list = db.Queryable<StudentX>().Where(it=>it.StudentId==2 || it.StudentId==3).ToList();db.ThenMapper(list, stu =>{stu.SchoolX = db.Queryable<SchoolX>().Where(scl => scl.SchoolId > 1).SetContext(scl => scl.SchoolId, () => stu.SchoolId, stu).FirstOrDefault();});string Jsonstr = db.Utilities.SerializeObject(list);

2.2 实现无线层

用到的实体类:

    //省份public class Province{[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]public int Pid { get; set; }public string Pname { get; set; }[SugarColumn(IsIgnore = true)]public List<City> cityList { get; set; }}//市级public class City{[SugarColumn(IsPrimaryKey = true)]public int Cid { get; set; }public string Cname { get; set; }[SugarColumn(IsIgnore = true)]public List<District> districtList { get; set; }public int pid { get; set; }}//区级public class District{[SugarColumn(IsPrimaryKey = true)]public int Did { get; set; }public string Dname { get; set; }[SugarColumn(IsIgnore = true)]public List<Town> townList { get; set; }public int cid { get; set; }}//镇public class Town{[SugarColumn(IsPrimaryKey = true)]public int Tid { get; set; }public string Tname { get; set; }[SugarColumn(IsIgnore = true)]public List<Village> villageList { get; set; }public int did { get; set; }}//村public class Village{[SugarColumn(IsPrimaryKey = true)]public int Vid { get; set; }public string Vname { get; set; }public int tid { get; set; }}

插入数据:

NSERT INTO `province` VALUES (1, '山东省');INSERT INTO `city` VALUES (1, '烟台市', 1);
INSERT INTO `city` VALUES (2, '青岛市', 1);
INSERT INTO `city` VALUES (3, '威海市', 1);INSERT INTO `district` VALUES (1, '开发区', 1);
INSERT INTO `district` VALUES (2, '莱山区', 1);
INSERT INTO `district` VALUES (3, '崂山区', 2);INSERT INTO `town` VALUES (1, '大新店镇', 1);
INSERT INTO `town` VALUES (2, '刘家沟镇', 1);
INSERT INTO `town` VALUES (3, '北沟镇', 1);
INSERT INTO `town` VALUES (4, '解甲庄', 2);INSERT INTO `village` VALUES (1, '大呼家村', 1);
INSERT INTO `village` VALUES (2, '回家村', 1);
INSERT INTO `village` VALUES (3, '刘家沟村', 2);
INSERT INTO `village` VALUES (4, '安乡刘家村', 2);
INSERT INTO `village` VALUES (5, '北沟一村', 3);
INSERT INTO `village` VALUES (6, '北沟二村', 3);

代码:

var list = db.Queryable<Province>().ToList();
db.ThenMapper(list, pro =>
{pro.cityList = db.Queryable<City>().SetContext(c => c.pid, () => pro.Pid, pro).ToList();
});
db.ThenMapper(list.SelectMany(it => it.cityList), city =>
{city.districtList = db.Queryable<District>().SetContext(d => d.cid, () => city.Cid, city).ToList();
});
db.ThenMapper(list.SelectMany(it => it.cityList).SelectMany(it => it.districtList), dis =>
{dis.townList = db.Queryable<Town>().SetContext(t => t.did, () => dis.Did, dis).ToList();
});
db.ThenMapper(list.SelectMany(it => it.cityList).SelectMany(it => it.districtList).SelectMany(it => it.townList), tow =>
{tow.villageList = db.Queryable<Village>().SetContext(v => v.tid, () => tow.Tid, tow).ToList();
});string Jsonstr = db.Utilities.SerializeObject(list);

文档参考:导航查询

SqlSugar 6.导航查询相关推荐

  1. 比较爽的导航查询 功能 .NET ORM / SqlSugar

    美女镇楼! .NET ORM 新概念导航 今天这篇文章分享一款好用简单的ORM框架 SqlSugar ,相比 EF Core的导航查询 更加简单 ,配置更加容易,几分钟就能上手. 1.导航查询特点 作 ...

  2. 期刊、文件、导航查询网站介绍,解决学术资源查找问题

    期刊.文件.导航查询网站介绍,可以帮助科研人员解决学术资源查找问题. 1.维普资讯(期刊查询) 2.Everything(文件查找) 3.科塔导航(学术网站聚合) 维普咨询: 维普期中文期刊服务平台, ...

  3. SqlSugar 1.基础查询

    文章目录 用到的表结构.数据.实体类 Student 1.查所有 2.按条件查询 3.多条件查询 4.动态OR查询 5.模糊查询 6.根据主键查询 7.查询第一条 8.查前几条 9.数据行数 10.设 ...

  4. Hibernate(九)HQL查询

    一.Hibernate提供的查询方式 OID查询方式:主键查询.通过get()或者load()方法加载指定OID的对象查询结果为一个 HQL查询方式:通过Query接口使用HQL语言进行查询 QBC查 ...

  5. .Net转Java自学之路—Hibernate框架篇三(查询方式)

    Hibernate查询方式: 1.对象导航查询:根据id查询出一的数据,再根据一的查询结果查询多的数据. OnlyClass only=session.get(OnlyClass.class,1); ...

  6. Hibernate【查询、连接池、逆向工程】

    2019独角兽企业重金招聘Python工程师标准>>> 前言 在Hibernate的第二篇中只是简单地说了Hibernate的几种查询方式....到目前为止,我们都是使用一些简单的主 ...

  7. sqlsugar 批量删除guid类型主键_一文上手SqlSugar 「C# 数据操作系列」

    0. 前言 前言,暂时挥别NHibernate(虽然我突然发现这玩意还挺有意思的,不过看得人不多).大步进入了有很多小伙伴向我安利的SQLSugar,嗯,我一直叫SugarSQL,好像是这个吧? 这是 ...

  8. Hibernate框架--学习笔记(下):hibernate的查询方式、多表查询、检索策略、批量抓取

    一.hibernate的查询方式: 主要有五种:对象导航查询:OID查询:hql查询:QBC查询:本地sql查询. 1.对象导航查询:根据id查询某个客户,再查询这个客户里面所有的联系人. 2.OID ...

  9. Hibernate 笔记 HQL查询

    http://www.cnblogs.com/zilong882008/archive/2011/11/05/2237123.html Hibernate 笔记 HQL查询(一)单属性,多属性查询 H ...

最新文章

  1. SQL Server 2014聚集列存储索引
  2. SCCM2012SP1---配置客户端发现方法和边界组
  3. web系统 手机app 能访问吗?_苹果手机能下载什么好用的桌面便签?有什么好的便签app推荐吗...
  4. 入门训练 A+B问题 c语言
  5. golang mysql封装_自己封装的golang 操作数据库方法
  6. java难学还是pythonnanxue_关于python:为什么numpy中的“ NaN”比“ -np.inf”更小?
  7. Android Native Hook工具
  8. 智能视频监控中的多目标跟踪分析
  9. Arduino颜色分类器
  10. 阿里云短信接口写法参照实例
  11. 实现微信小程序开发的基本步骤
  12. 用牛顿迭代法求方程2x^3-4x^2+3x-6=0在1.5附近的解,要求误差小于1e-5
  13. centos python3, There was a problem confirming the ssl certificate
  14. Unity播放视频OGV格式视频
  15. Autocad2015点开闪退问题,线段等分
  16. 三级分销系统哪家好?360shop
  17. C语言基础-函数的概念
  18. 经典SVM之SMO算法实现
  19. Android:TextView和EditText
  20. TEA、XTEA、XXTEA加密解密算法(C语言实现)

热门文章

  1. 借助Process Monitor(ProcMon.exe)逆向一个CrackMe
  2. 道路交通标志设计要素和基本原则
  3. 惠普计算机不启动不了系统还原,惠普电脑win10进不了系统怎么恢复系统
  4. 微信小程序---微信头像、名称获取一次后即可使用
  5. Java基本语法(初学者必看,值得收藏)
  6. es的refresh和flush介绍
  7. GO 常见环境变量与常用命令
  8. 特惠快车和快车的区别,滴滴特惠快车老司机说了实话?
  9. 用proteus来玩二极管或门电路
  10. 基于Arduino Uno开发板的红外遥控开发