tnblog
首页
视频
资源
登录

.NET ORM核心功能之导航属性- EFCore和 SqlSugar 。SqlSugar 2023年导航新功能

3078人阅读 2023/6/14 9:56 总访问:824532 评论:0 收藏:0 手机
分类: ORM

导航属性

导航属性是作为.NET ORM核心功能中的核心,在SqlSugar没有支持导航属性前,都说只是一个高级DbHelper, 经过3年的SqlSugar重构
已经拥有了一套
非常成熟的导航属性体系,本文不是重点讲SqlSugar而是重点讲导航属性的作用,让更多写Sql人还未使用ORM的人了解到ORM的作用。

1.复杂的查询过滤

用户根据权限过滤,用户根据组织过滤 等这种多对多情况用SQL就相当复杂 ,例如:用SQL写一个多对多过滤就要联3个表(主表 中间表 从表),如果
Where中用到多个多对多或者嵌套多对多那写SQL简直就是恶梦 (一对多和一对一也有提升,没有多对多明显)

  1. //EF CORE查询
  2. var Persons= dbContext.Person //需要定义DbSet才能点出来
  3. .Where(it=>it.Files.Any(y=>y.ChildFiles.Any(s=>s.name=="A"))).ToList()
  4. //SqlSugar 查询
  5. var Persons= dbContext.Queryable()
  6. .Where(it=>it.Files.Any(y=>y.ChildFiles.Any(s=>s.name=="A"))).ToList()

用SQL写如下:

  1. SELECT p.*
  2. FROM Person p
  3. WHERE EXISTS (
  4. SELECT 1
  5. FROM PersonFile pf
  6. INNER JOIN File f ON pf.FileId = f.FileId
  7. INNER JOIN PersonFile pf2 ON f.FileId = pf2.FileId
  8. WHERE pf.PersonId = p.PersonId
  9. AND pf2.PersonId IN (
  10. SELECT p2.PersonId
  11. FROM Person p2
  12. INNER JOIN PersonFile pf3 ON p2.PersonId = pf3.PersonId
  13. INNER JOIN File f2 ON pf3.FileId = f2.FileId
  14. WHERE f2.name = 'A'
  15. )
  16. )

像SAAS系统这种多对多用的非常多,特别在组织、用户、角色、文件等无处理不在,这也是为什么要用ORM的原因

2.复杂的表单提交

如果您的人事管理需要包含更多的信息,例如学历和工作经验等字段,您可以在代码中添加相应的实体和关联。
假设您有以下实体:人员(Person)、部门(Department)、职位(Position)、学历(Education)和工作经验(WorkExperience) 。

  1. var person = new Person
  2. {
  3. // 设置人员属性...
  4. Department = new Department
  5. {
  6. // 设置部门属性...
  7. },
  8. Position = new Position
  9. {
  10. // 设置职位属性...
  11. },
  12. Education = new Education
  13. {
  14. // 设置教育属性...
  15. },
  16. WorkExperience = new WorkExperience
  17. {
  18. // 设置工作经历属性...
  19. }
  20. };

代码如下:

  1. //SqlSugar 导航插入
  2. db.InsertNav(person)
  3. .Include(z1 => z1.Department)
  4. .Include(z1 => z1.Position)
  5. .Include(z1 => z1.Education)
  6. .Include(z1 => z1.WorkExperience)
  7. .ExecuteCommand();//导航插入 一句就能搞定,先插入主表,然后在根据主表的主键在插入从表,特别是自增列用导航代码清爽很多

3.多层级结构的查询

因为Sql本身就不支持对多层级结构查询,所以不用ORM想实现高性能的多层级结构是需要花大量精力去优化和写代码的

  1. //EF CORE查询
  2. var Persons= dbContext.Person
  3. .Include(z1 => z1.Department)
  4. .Include(z1 => z1.Position)
  5. .Include(z1 => z1.Education)
  6. .Include(z1 => z1.WorkExperience).ToList()

EF Core导航属性配置

EF多对多

  1. public class Student
  2. {
  3. public int StudentId { get; set; }
  4. public string StudentName { get; set; }
  5. // 其他学生属性...
  6. public virtual ICollection Courses { get; set; }
  7. }
  8. public class Course
  9. {
  10. public int CourseId { get; set; }
  11. public string CourseName { get; set; }
  12. // 其他课程属性...
  13. public virtual ICollection Students { get; set; }
  14. }
  15. public class StudentCourse
  16. {
  17. public int CourseId { get; set; }
  18. public int StudentId { get; set; }
  19. }
  20. // 配置多对多关系
  21. protected override void OnModelCreating(ModelBuilder modelBuilder)
  22. { modelBuilder.Entity()
  23. .HasMany(s => s.Courses)
  24. .WithMany(c => c.Students) .UsingEntity(j => j.ToTable("StudentCourse"));
  25. }

EF一对多和一对一

  1. public class Department
  2. {
  3. public int DepartmentId { get; set; }
  4. public string DepartmentName { get; set; }
  5. // 其他部门属性...
  6. public virtual ICollection Employees { get; set; }
  7. }
  8. public class Employee
  9. {
  10. public int EmployeeId { get; set; }
  11. public string EmployeeName { get; set; }
  12. // 其他员工属性...
  13. public int DepartmentId { get; set; }
  14. public virtual Department Department { get; set; }
  15. }
  16. // 配置一对多关系
  17. protected override void OnModelCreating(ModelBuilder modelBuilder)
  18. {
  19. modelBuilder.Entity()
  20. .HasMany(d => d.Employees)
  21. .WithOne(e => e.Department)
  22. .HasForeignKey(e => e.DepartmentId);
  23. }

SqlSugar导航属性配置

SqlSugar多对多

  1. //实体
  2. public class ABMapping1
  3. {
  4. [SugarColumn(IsPrimaryKey = true)]//中间表可以不是主键
  5. public int AId { get; set; }
  6. [SugarColumn(IsPrimaryKey = true)]//中间表可以不是主键
  7. public int BId { get; set; }
  8. }
  9. public class A1
  10. {
  11. [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
  12. public int Id { get; set; }
  13. public string Name { get; set; }
  14. [Navigate(typeof(ABMapping1), nameof(ABMapping1.AId), nameof(ABMapping1.BId))]//注意顺序
  15. public List BList { get; set; }//只能是null不能赋默认值
  16. }
  17. public class B1
  18. {
  19. [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
  20. public int Id { get; set; }
  21. public string Name { get; set; }
  22. [Navigat(typeof(ABMapping1), nameof(ABMapping1.BId), nameof(ABMapping1.AId))]//注意顺序
  23. public List AList { get; set; }//只能是null不能赋默认值
  24. }

Sqlugar一对一和一对多

  1. //实体
  2. public class StudentA
  3. {
  4. [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
  5. public int StudentId { get; set; }
  6. public string Name { get; set; }public int SchoolId { get; set; }
  7. [Navigate(NavigateType.OneToOne, nameof(SchoolId))]//一对一 SchoolId是StudentA类里面的
  8. public SchoolA SchoolA { get; set; } //不能赋值只能是null
  9. }
  10. public class SchoolA
  11. {
  12. [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
  13. public int Id{ get; set; }
  14. public string SchoolName { get; set; }
  15. [Navigate(NavigateType.OneToMany, nameof(BookA.studenId))]//一对多 BookA表中的studenId
  16. public List Books { get; set; }//注意禁止给books手动赋值
  17. }

SqlSugar 2023年导航新功能

SqlSugar 第一层自动导航

  1. var list3 = db.Queryable()
  2. .IncludesAllFirstLayer().ToList();//有重载可以排除不想要的
  3. //排除说明:
  4. //IncludesAllFirstLayer(nameof(UnitaStudentA.ProjectPhases))
  5. //这样就是排除ProjectPhases的导航属性
  6. //可以排除多个
  7. //IncludesAllFirstLayer("a","b")
  8. //自动导航如果有重复的情况: 谁在前面执行哪个
  9. var list3 = db.Queryable()
  10. .Includes(it=>it.Order.Where(s=>s.id==1).ToList())
  11. .IncludesAllFirstLayer().ToList();//自动导航和Order重复
  12. //根据名字导航
  13. db.Queryable()
  14. //等同于Includes(it=>it.ProjectPhases)
  15. .IncludesByNameString(nameof(Order.ProjectPhases)).ToList()

SqlSugar第二层半自动

  1. //自动写法,Books下面的A和B都会查询出来
  2. .IncludesAllSecondLayer(x=>x.Books) //自动只能有这么多层次,更深层级需要手动写法
  3. //手动写法
  4. .Includes(x => x.Books,x=>x.A)
  5. .Includes(x => x.Books,x=>x.B)

SqlSugar导航DTO转换

在前二年SqlSugar导航只能说够用,并不算好用,今年重点将导航DTO进行了强化

  1. //简单的用法 5.1.4.71
  2. var list = db.Queryable<Student_004>()
  3. .Includes(x => x.books)
  4. .Select(x => new Student_004DTO
  5. {
  6. books = x.books
  7. }, true)//true是自动映射其他属性,匿名对象需要手动
  8. .ToList();
  9. //Mapster转换 5.1.4.71
  10. var list = db.Queryable<Student_004>()
  11. .Includes(x => x.books)
  12. .Select(x => new Student_004DTO
  13. {
  14. name=x.Name,
  15. books = x.books.Adapt<List<BooksDTO>>() //导航对象用 Mapster转换 (NUGET安装)
  16. })
  17. .ToList();
  18. //DTO中用方法 5.1.4.71
  19. var list = db.Queryable<Student_004>()
  20. .Includes(x => x.books)
  21. .Select(x => new Student_004DTO
  22. {
  23. name=x.Name,
  24. //可以是C#任何方法结尾
  25. bookIds=x.books.Select(it=>it.id).ToList()
  26. })
  27. .ToList();
  28. //联表查询用DTO写法 5.1.4.71
  29. var list5= db.Queryable<Student_004>()
  30. .Includes(x => x.school_001, x => x.rooms)
  31. .Includes(x => x.books)
  32. .LeftJoin<Order>((x, y) => x.Id==y.sid)
  33. .Select((x,y) => new Student_004DTO
  34. {
  35. SchoolId = x.SchoolId,
  36. books = x.books,
  37. school_001 = x.school_001,
  38. Name=y.Name
  39. })
  40. .ToList();

当你遇到繁琐的数据库操作时,.NET SQLSugar就像是一双温暖的手,帮你轻松解决难题。它是一个强大的工具,让你的数据库管理变得更简单、更高效。下载.NET SQLSugar吧,让它成为你的数据之路上的得力助手,让你的编程之旅充满感动与喜悦!

原码下载: https://github.com/DotNetNext/SqlSugar

总结:

.NET中无论是EF CORE还是SQLSUGAR 使用了导航属性都不再需要费心写繁琐的SQL语句,只需简单地调用导航属性,便能轻松获取所需的数据。让我们一起追随这份感动,选择使用导航属性,让编程的旅途更加愉悦,让代码的世界充满美好与便捷!

原文:https://www.cnblogs.com/sunkaixuan/p/17457497.html


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

css图片文字对齐问题

文字和图片写到一排经常会出现对不齐的问题 这样感觉图片会上来一点没有和文字对齐,如下图 但是如果修改下html结...

微信交易单号订单号的区别

一般第三方在线支付系统中都会有两类订单号transactionId 为支付系统的订单号,由支付系统生成,并在回调时传回给商户,用...

C ?、?? 问号2个问号的用法(类型?、对象?)

C# ?C# ???:单问号1.定义数据类型可为空。可用于对int,double,bool等无法直接赋值为null的数据类型进行null的赋值如这...

C out、ref关键字的用法区别

说说自己对out、ref的认识,面试问到的几率很高哟。out:classProgram { /* *out、ref都是引用传递,传递后使用都会改变...

SQL Server的几种分页方式效率

--topnotin方式 selecttop条数*fromtablename whereIdnotin(selecttop条数*页数Idfromtablename) --ROW_NUMBER()O...

Java中的堆栈以及堆栈的区别

在正式内容开始之前要说明一点,我们经常所说的堆栈堆栈是堆和栈统称,堆是堆,栈是栈,合在一起统称堆栈;  1.栈(stack)...

JSON对象JSON字符串的区别

JSON对象是直接可以使用JQuery操作的格式,如C#中可以用对象(类名)点出属性(方法)一样var str2 = { &quot;name&quot;: ...

css中单位pxem,remvh/vw的理解

&gt;px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。em是相对长度单位。相对于当前对象内文本的字...

redis中主从、哨兵集群这三个有什么区别

主从模式:备份数据、负载均衡,一个Master可以有多个Slaves。sentinel(哨兵)发现master挂了后,就会从slave中重新选举一个...

用Linq解决商品其下sku的筛选排序查询

本是sql to linq的东西,但是用的框架是.core 2.1,所以就归到core里吧最近遇到一个稍微复杂点的小问题需求:商城的商品列...

谈谈对事件委托的理解

对于c#的程序员来说,事件和委托可能是一道坎,过去的人觉得很简单,没过去的人觉得这个堵得慌 ,每次用着都很难受。本人就...

渣渣学安卓之banner图首页布局

接上文,登录页写完,该上首页了。找度娘搜索 安卓APP首页布局,想借鉴下,没搜到相关代码。只能赶鸭子上架,自己琢磨。效...

渣渣学安卓之时间选择器文本框操作

一、时间选择器有时候我们做页面时需要时间选择器,先上效果图看了下android studio,没有这个样式的控件,找了下度娘发现...

session的简单使用CookieSession区别

Cookie禁用掉,session会不会受影响?Cookie被禁用掉,session也不能用了因为Sessionid是存储在cookie中Cookie和Session区...

思宇课后实例—全选部分选中

jQuery课后实例昨天我们初次写了全(不)选和反选功能,今天我们来写下它的变种功能1.首先我们老规矩,来看下需求2.然后我们...
这一生多幸运赶上过你.
排名
8
文章
221
粉丝
7
评论
7
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术