導(dǎo)航屬性
導(dǎo)航屬性是作為.NET ORM核心功能中的核心,在SqlSugar沒(méi)有支持導(dǎo)航屬性前,都說(shuō)只是一個(gè)高級(jí)DbHelper, 經(jīng)過(guò)3年的SqlSugar重構(gòu)已經(jīng)擁有了一套
非常成熟的導(dǎo)航屬性體系,本文不是重點(diǎn)講SqlSugar而是重點(diǎn)講導(dǎo)航屬性的作用,讓更多寫Sql人還未使用ORM的人了解到ORM的作用。
?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-471916.html
1.復(fù)雜的查詢過(guò)濾
用戶根據(jù)權(quán)限過(guò)濾,用戶根據(jù)組織過(guò)濾 等這種多對(duì)多情況用SQL就相當(dāng)復(fù)雜 ,例如:用SQL寫一個(gè)多對(duì)多過(guò)濾就要聯(lián)3個(gè)表(主表 中間表 從表),如果
Where中用到多個(gè)多對(duì)多或者嵌套多對(duì)多那寫SQL簡(jiǎn)直就是惡夢(mèng) (一對(duì)多和一對(duì)一也有提升,沒(méi)有多對(duì)多明顯)
//EF CORE查詢 var Persons= dbContext.Person //需要定義DbSet才能點(diǎn)出來(lái) .Where(it=>it.Files.Any(y=>y.ChildFiles.Any(s=>s.name=="A"))).ToList() //SqlSugar 查詢 var Persons= dbContext.Queryable<Person>() .Where(it=>it.Files.Any(y=>y.ChildFiles.Any(s=>s.name=="A"))).ToList()
用SQL寫如下:
SELECT p.* FROM Person p WHERE EXISTS ( SELECT 1 FROM PersonFile pf INNER JOIN File f ON pf.FileId = f.FileId INNER JOIN PersonFile pf2 ON f.FileId = pf2.FileId WHERE pf.PersonId = p.PersonId AND pf2.PersonId IN ( SELECT p2.PersonId FROM Person p2 INNER JOIN PersonFile pf3 ON p2.PersonId = pf3.PersonId INNER JOIN File f2 ON pf3.FileId = f2.FileId WHERE f2.name = 'A' ) )
像SAAS系統(tǒng)這種多對(duì)多用的非常多,特別在組織、用戶、角色、文件等無(wú)處理不在,這也是為什么要用ORM的原因
?
2.復(fù)雜的表單提交
如果您的人事管理需要包含更多的信息,例如學(xué)歷和工作經(jīng)驗(yàn)等字段,您可以在代碼中添加相應(yīng)的實(shí)體和關(guān)聯(lián)。
假設(shè)您有以下實(shí)體:人員(Person)、部門(Department)、職位(Position)、學(xué)歷(Education)和工作經(jīng)驗(yàn)(WorkExperience)。
var person = new Person { // 設(shè)置人員屬性... Department = new Department { // 設(shè)置部門屬性... }, Position = new Position { // 設(shè)置職位屬性... }, Education = new Education { // 設(shè)置教育屬性... }, WorkExperience = new WorkExperience { // 設(shè)置工作經(jīng)歷屬性... } };
代碼如下:
//SqlSugar 導(dǎo)航插入 db.InsertNav(person) .Include(z1 => z1.Department) .Include(z1 => z1.Position) .Include(z1 => z1.Education) .Include(z1 => z1.WorkExperience) .ExecuteCommand();//導(dǎo)航插入 一句就能搞定,先插入主表,然后在根據(jù)主表的主鍵在插入從表,特別是自增列用導(dǎo)航代碼清爽很多
?
3.多層級(jí)結(jié)構(gòu)的查詢
因?yàn)镾ql本身就不支持對(duì)多層級(jí)結(jié)構(gòu)查詢,所以不用ORM想實(shí)現(xiàn)高性能的多層級(jí)結(jié)構(gòu)是需要花大量精力去優(yōu)化和寫代碼的
//EF CORE查詢 var Persons= dbContext.Person .Include(z1 => z1.Department) .Include(z1 => z1.Position) .Include(z1 => z1.Education) .Include(z1 => z1.WorkExperience).ToList()
?
EF Core導(dǎo)航屬性配置
EF多對(duì)多
public class Student { public int StudentId { get; set; } public string StudentName { get; set; } // 其他學(xué)生屬性... public virtual ICollection<Course> Courses { get; set; } } public class Course { public int CourseId { get; set; } public string CourseName { get; set; } // 其他課程屬性... public virtual ICollection<Student> Students { get; set; } } public class StudentCourse { public int CourseId { get; set; } public int StudentId { get; set; } } // 配置多對(duì)多關(guān)系 protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Student>() .HasMany(s => s.Courses) .WithMany(c => c.Students) .UsingEntity(j => j.ToTable("StudentCourse")); }
EF一對(duì)多和一對(duì)一
public class Department { public int DepartmentId { get; set; } public string DepartmentName { get; set; } // 其他部門屬性... public virtual ICollection<Employee> Employees { get; set; } } public class Employee { public int EmployeeId { get; set; } public string EmployeeName { get; set; } // 其他員工屬性... public int DepartmentId { get; set; } public virtual Department Department { get; set; } } // 配置一對(duì)多關(guān)系 protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Department>() .HasMany(d => d.Employees) .WithOne(e => e.Department) .HasForeignKey(e => e.DepartmentId); }
?
SqlSugar導(dǎo)航屬性配置
SqlSugar多對(duì)多
//實(shí)體 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; }//只能是null不能賦默認(rèn)值 } 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; }//只能是null不能賦默認(rèn)值 }
?
Sqlugar一對(duì)一和一對(duì)多
//實(shí)體 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))]//一對(duì)一 SchoolId是StudentA類里面的 public SchoolA SchoolA { get; set; } //不能賦值只能是null } public class SchoolA { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int Id{ get; set; } public string SchoolName { get; set; } [Navigate(NavigateType.OneToMany, nameof(BookA.studenId))]//一對(duì)多 BookA表中的studenId public List<BookA> Books { get; set; }//注意禁止給books手動(dòng)賦值 }
?
SqlSugar 2023年導(dǎo)航新功能
SqlSugar 第一層自動(dòng)導(dǎo)航
var list3 = db.Queryable<UnitaStudentA>() .IncludesAllFirstLayer().ToList();//有重載可以排除不想要的 //排除說(shuō)明: //IncludesAllFirstLayer(nameof(UnitaStudentA.ProjectPhases)) //這樣就是排除ProjectPhases的導(dǎo)航屬性 //可以排除多個(gè) //IncludesAllFirstLayer("a","b") //自動(dòng)導(dǎo)航如果有重復(fù)的情況: 誰(shuí)在前面執(zhí)行哪個(gè) var list3 = db.Queryable<UnitaStudentA>() .Includes(it=>it.Order.Where(s=>s.id==1).ToList()) .IncludesAllFirstLayer().ToList();//自動(dòng)導(dǎo)航和Order重復(fù) //根據(jù)名字導(dǎo)航 db.Queryable<Order>() //等同于Includes(it=>it.ProjectPhases) .IncludesByNameString(nameof(Order.ProjectPhases)).ToList()
SqlSugar第二層半自動(dòng)
//自動(dòng)寫法,Books下面的A和B都會(huì)查詢出來(lái) .IncludesAllSecondLayer(x=>x.Books) //自動(dòng)只能有這么多層次,更深層級(jí)需要手動(dòng)寫法 //手動(dòng)寫法 .Includes(x => x.Books,x=>x.A) .Includes(x => x.Books,x=>x.B)
SqlSugar導(dǎo)航DTO轉(zhuǎn)換
在前二年SqlSugar導(dǎo)航只能說(shuō)夠用,并不算好用,今年重點(diǎn)將導(dǎo)航DTO進(jìn)行了強(qiáng)化
//簡(jiǎn)單的用法 5.1.4.71 var list = db.Queryable<Student_004>() .Includes(x => x.books) .Select(x => new Student_004DTO { books = x.books }, true)//true是自動(dòng)映射其他屬性,匿名對(duì)象需要手動(dòng) .ToList(); //Mapster轉(zhuǎn)換 5.1.4.71 var list = db.Queryable<Student_004>() .Includes(x => x.books) .Select(x => new Student_004DTO { name=x.Name, books = x.books.Adapt<List<BooksDTO>>() //導(dǎo)航對(duì)象用 Mapster轉(zhuǎn)換 (NUGET安裝) }) .ToList(); //DTO中用方法 5.1.4.71 var list = db.Queryable<Student_004>() .Includes(x => x.books) .Select(x => new Student_004DTO { name=x.Name, //可以是C#任何方法結(jié)尾 bookIds=x.books.Select(it=>it.id).ToList() }) .ToList(); //聯(lián)表查詢用DTO寫法 5.1.4.71 var list5= db.Queryable<Student_004>() .Includes(x => x.school_001, x => x.rooms) .Includes(x => x.books) .LeftJoin<Order>((x, y) => x.Id==y.sid) .Select((x,y) => new Student_004DTO { SchoolId = x.SchoolId, books = x.books, school_001 = x.school_001, Name=y.Name }) .ToList();
當(dāng)你遇到繁瑣的數(shù)據(jù)庫(kù)操作時(shí),.NET SQLSugar就像是一雙溫暖的手,幫你輕松解決難題。它是一個(gè)強(qiáng)大的工具,讓你的數(shù)據(jù)庫(kù)管理變得更簡(jiǎn)單、更高效。下載.NET SQLSugar吧,讓它成為你的數(shù)據(jù)之路上的得力助手,讓你的編程之旅充滿感動(dòng)與喜悅!
原碼下載:?https://github.com/DotNetNext/SqlSugar
?
總結(jié):
.NET中無(wú)論是EF CORE還是SQLSUGAR 使用了導(dǎo)航屬性都不再需要費(fèi)心寫繁瑣的SQL語(yǔ)句,只需簡(jiǎn)單地調(diào)用導(dǎo)航屬性,便能輕松獲取所需的數(shù)據(jù)。讓我們一起追隨這份感動(dòng),選擇使用導(dǎo)航屬性,讓編程的旅途更加愉悅,讓代碼的世界充滿美好與便捷!文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-471916.html
?
到了這里,關(guān)于.NET ORM核心功能之導(dǎo)航屬性- EFCore和 SqlSugar的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!