1、导航查询特点

作用:主要处理主对象里面有子对象这种层级关系查询

1.1 无外键开箱就用

其它ORM导航查询 需要 各种配置或者外键,而SqlSugar则开箱就用,无外键,只需配置特性和主键就能使用

1.2 高性能优

查询 性能非常强悍   5.0.8.1preview02版本进行了性能优化

支持大数据分页导航查询

3.3 语法超级爽

 var list=db.Queryable<Test>()
           .Includes(t=> t.Provinces, pro=>pro.Citys ,cit=>cit.Street) //多层级
           .Includes(t=> t.ClassInfo)// 一个层级查询
           .ToList();              
                
 //具体用法看下面文档介绍
 //多层级可以看2.5

2、新导航查询

适合有主键的常规操作, 请升级到5.0.6.8

2.1 一对一 ( one to one )

//实体
public class StudentA
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int StudentId { getset; }
    public string Name { getset; }
    public  string SexCode { get;set;}
    public int SchoolId { getset; }
     
    //用例1:主键模式 StudentA(主表)表中的 SchoolId 和SchoolA(子表)中的主键关联 
    [Navigate(NavigateType.OneToOne, nameof(SchoolId))]//一对一 SchoolId是StudentA类里面的
    public SchoolA SchoolA { getset; } //不能赋值只能是null
     
    //用例2:反向导航,2个字段匹配关系 
    [Navigate(NavigateType.OneToOne, nameof(SchoolId),nameof(SchoolA.Id))] 
    public SchoolA SchoolA { getset; } //不能赋值只能是null
    //第一个主表字段,第二从表字段  顺序不要错了
     
    //用例3: 字典导航 多了个SQL条件参数  
    //[SqlSugar.Navigate(NavigateType.OneToOne,nameof(SexId),nameof(DataDictionary1.Code),"type='sex'")]
    //具体用法可以看配置查询 https://www.donet5.com/Home/Doc?typeId=2309
 
}
public class SchoolA
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int Id{ getset; }
    public string SchoolName { getset; }
 
//导航+主表过滤  导航属性过滤
var list = db.Queryable<StudentA>()
         .Includes(x => x.SchoolA) //填充子对象 (不填充可以不写)
         .Where(x =>x.SchoolA.SchoolName=="北大"
         .ToList();
 
 
//导航+主表过滤  只查有导航数据 (新功能:5.1.2.8)
var list = db.Queryable<StudentA>()
         .Includes(x => x.SchoolA) //填充子对象 (不填充可以不写)
         .Where(x => SqlFunc.Exists(x.SchoolA.主键))
         .ToList();            
                          
          
//导航+子表过滤 5.0.9.4-preview06 请注意升级 
//创建一个扩展函数,默认是Class不支持Where
public static List<T> Where<T>(this T thisValue, Func<T,bool> whereExpression ) where T:class,new()
{
   return new List<T>() { thisValue };
var list = db.Queryable<Student_003>()
          .Includes(x => x.school_001.Where(z=>z.Name=="a").ToList())//扩展的Where对子表进行过滤
          .ToList(); //5.0.9.4-preview06 才支持 请注意升级 请注意升级
 
//导航 指定字段 5.1.3.38
var list = db.Queryable<StudentA>()
         .Includes(x => x.SchoolA.ToList(it=>new SchoolA(){ Name =it.Name,id=it.Id})) 
         .ToList();                    
           
           
//导航如果只查一个字段         
var list = db.Queryable<StudentA>()
             .Where(x => x.id>1)  //Where和Select中别名要写一样
             .Select(x =>new 
                x=x,
                SchoolName= x.SchoolA.SchoolName
             }).ToList();

多字段1对1 看文档2.4

2.2 一对多 ( one to many)

BookA(子表)中的studenId和StudentA(主表)中的主键关联

//实体
public class StudentA
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int Id{ getset; }
    public string Name { getset; }
    public int SchoolId { getset; }
     
    //用例1:正常一对多
    [Navigate(NavigateType.OneToMany, nameof(BookA.studenId))]//BookA表中的studenId
    public List<BookA> Books { getset; }//注意禁止给books手动赋值
     
    //用例2:反向导航支持:StudentA没有主键或者指定关系
    [Navigate(NavigateType.OneToMany, nameof(BookA.studenId),nameof(Id))] 
    public List<BookA> Books { getset; }//注意禁止给books手动赋值
    //与一对一相反 第一个 从表字段,第二个主表字段
 
}
public class BookA
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int BookId { getset; }
    public string Name { getset; }
    public int studenId { getset; }
}
 
//例1:简单用法
var list = db.Queryable<StudentA>()
.Includes(x => x.Books)
.ToList();
 
//例2:支持Any和Count 对主表进行过滤 (子对象过滤看下面)
var list = db.Queryable<StudentA>()
.Includes(x => x.Books)
.Where(x => x.Books.Any())
//带条件的
//.Where(x => x.Books.Any(z=>z.Name=="jack")))
.ToList();
 
//例3: 没有Includes也可以使用过滤
var list2 = db.Queryable<StudentA>()
.Where(x => x.Books.Any())//Any中可以加条件 Any(z=>z.BookId==1)
.ToList();                         
 
 
//例4 Where子对象进行排序和过滤 (支持WhereIF)
var list = db.Queryable<StudentA>()
  .Includes(x => x.Books.Where(y => y.BookId > 0).OrderBy(y => y.BookId).ToList())
  .ToList();
   
//例5 主表+子表都过滤
var list = db.Queryable<StudentA>()
.Includes(x => x.Books.Where(it=>it.Name=="jack"))//只过滤子表
.Where(x => x.Books.Any(z=>z.Name=="jack")))//通过子表过滤主表
.ToList();
   
//例6:Select指定字段
var list= db.Queryable<StudentA>()
           .Includes(x => x.Books.Select(z=>new BookA() { Names = z.Names }).ToList()) 
 
//例7:Select多层级  (结构:StudentAt->books->BookItems)      
var list= db.Queryable<StudentA>()
     .Includes(x => x.Books.Select(z=>new BookA(){Names=z.Name}.ToList(),it=>BookItems)) 
    .ToList();、//Includes中的Select只能是字段 ,不能导航对象           
            
            
//例8:OrderBy指定字段 (Skip Take可以分页)
var list= db.Queryable<StudentA>()
           .Includes(x => x.Books.OrderBy(z=>z.Id).ToList()) 
           .ToList();
            
//例9:Take取前几条
var list= db.Queryable<StudentA>()
           .Includes(x => x.Books.Take(10).ToList()) 
           .ToList();          
                       
            
//例10:DTO支持进行了强化   
看标题2.7        
            
            
//例11:一对多后还可用追加字段映射MappingField 如果以前是1个字关联,现在追加后就成了1+1       
db.Queryable<StudentA>().Includes(x => x.Books.MappingField(z=>z.字段,()=>x.字段).ToList() )
                .ToList();
//MappingField 和 Where区别
//MappingField MappingField用来指定2个对象的关系,Where只能当前表过滤不能和主表进行关联 
//MappingField 可以多个也可以和Where一起始用

非标准1对多 看文档2.4

2.3 多对多 ( many to many)

//实体
public class ABMapping1
{
    [SugarColumn(IsPrimaryKey = true)]//中间表可以不是主键
    public int AId { getset; }
    [SugarColumn(IsPrimaryKey = true)]//中间表可以不是主键
    public int BId { getset; }
}
public class A1
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int Id { getset; }
    public string Name { getset; }
    [Navigate(typeof(ABMapping1), nameof(ABMapping1.AId), nameof(ABMapping1.BId))]//注意顺序
    public List<B1> BList { getset; }//只能是null不能赋默认值
}
public class B1
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int Id { getset; }
    public string Name { getset; }
    [Navigat(typeof(ABMapping1), nameof(ABMapping1.BId), nameof(ABMapping1.AId))]//注意顺序
    public List<A1> AList { getset; }//只能是null不能赋默认值
}  
//例1:简单用法 直接填充B的集合,只要配置好特性非常简单
var list3= db.Queryable<A1>().Includes(x => x.BList).ToList(); 
 
 //例2:支持子对象排序和过滤 (支持WhereIF)
var list3= db.Queryable<A1>().Includes(x => x.BList.Where(z=>z.Id>0).ToList()).ToList(); 
 
 //例3:支持主表过滤  Any和Count
var list3= db.Queryable<A1>().Includes(x => x.BList)
                .Where(x=>x.BList.Any())//Any里面可以加条件 Any(z=>z.xxxx>0)
                .ToList();
 //例4主表+子表都过滤
var list = db.Queryable<StudentA>()
   .Includes(x => x.BList.Where(it=>it.Name=="jack"))//只过滤子表
   .Where(x => x.BList.Any(z=>z.Name=="jack")))//通过子表过滤主表
   .ToList();               
                 
//不使用Includes一样可以过滤              
var list3= db.Queryable<A1>() 
                .Where(x=>x.BList.Any()) //可以加条件.Where(x=>x.BList.Any(z=>z.xxx==x.yyy))
                .ToList();                
                 
//多对多后还可用追加字段映射MappingField 如果以前是2个字段关联,现在追加后就成了2+1       
db.Queryable<A1>().Includes(x => x.BList.MappingField(z=>z.字段,()=>x.字段).ToList()  )
                .ToList();
//MappingField 和 Where区别
//MappingField MappingField用来指定2个对象的关系,Where只能当前表过滤不能和主表进行关联 
//MappingField 可以多个也可以和Where一起始用

2.4  多字段关系映射(可以是N个)

支持多个字段关联  5.1.4.108-preview32

var list=db.Queryable<UnitAddress011>().Includes(x => x.Persons).ToList();
   
//m是主表字段 c是子表字段 是一个json数组 格式不要错了 
[Navigate(NavigateType.Dynamic, "[{m:\"Id\",c:\"AddressId\"},{m:\"Id2\",c:\"AddressId2\"}]")]
public List<UnitPerson011> Persons { getset; }

注意:该功能只能用在查询上,能用正常导航就尽量使用正常导航

2.5 多级导航(例如:省>市>区)

配置好实体类,我们可以多级查询(一对多、一对多、多对多都支持只要配好类就可以使用)

public class StudentA
{
    [SugarColumn(IsPrimaryKey = true)]
    public int StudentId { getset; }
    public string Name { getset; }
    public int SchoolId { getset; }
    [Navigate(NavigateType.OneToOne, nameof(SchoolId))]//一对一
    public SchoolA SchoolA { getset; }
    [Navigate(NavigateType.OneToMany, nameof(BookA.studenId))]//一对多
    public List<BookA> Books { getset; }//只能是null不能赋默认值
 
}
public class SchoolA
{
    [SugarColumn(IsPrimaryKey = true)]
    public int SchoolId { getset; }
    public string SchoolName { getset; }
    [Navigate(NavigateType.OneToMany, nameof(RoomA.SchoolId))]//一对多
    public List<RoomA> RoomList { getset; }//只能是null不能赋默认值
}
 
public class RoomA
{
    [SugarColumn(IsPrimaryKey = true)]
    public int RoomId { getset; }
    public string RoomName { getset; }
    public int SchoolId { getset; }
}
public class BookA
{
    [SugarColumn(IsPrimaryKey = true)]
    public int BookId { getset; }
 
    public string Name { getset; }
    public int studenId { getset; }
}       
 
var list2 = db.Queryable<StudentA>()
             //查2层
             .Includes(st => st.SchoolA, sch=> sch.RoomList)//查询2级(等于EF ThenInclude)
             //查1层
             .Includes(st=> st.Books)  
             .ToList()
//说明: 一对多 多对多 一对多 只要配好了都可以多层级使用
  
              
//如果想超过3个层级需要.AsNavQueryable()
//缺点VS提示会消失,直接写不要在乎意提示不出来,VS关掉在开就行了,只要不改这个代码提示就不会有问题
db.Queryable<Order>()
    Includes(it=>it.xx)
    .AsNavQueryable()//加这个前面
    .Includes(it=>it.1,it=>it.2,it=>it.3,it=>it.4,it=>it.5..)
//.AsNavQueryable()能不用尽量不要用,正常Includes(+3)重载完全够用了

2.6 性能优化

1、升级 如果搜索不到勾选预览版本

5.0.8.1 preview02版本针对大数据导航有了很好的性能优化

2、分页导航

底层分批量查询 适合一次性查询1000条以上的导航

    var list = new List<Tree1>();
 
    db.Queryable<Tree1>()
        .Includes(it => it.Child)
        .ForEach(it => list.Add(it), 300); //每次查询300条

更多用法:https://www.donet5.com/Home/Doc?typeId=2414

3、关联字段推荐用主键,如果非主键导航加索引为佳

2.7 转DTO (必学的技巧)

1.自动DTO (推荐 )

//Mapster 工具映射 (推荐) 比AutoMapper方便不需要配置
//Nuget直接安装就行了
 
//简单示例:结构一样直接转换
var list=db.Queryable<StudentA>()
           .Includes(x => x.Books).ToList();
var dtoList=list.Adapt<List<StudentDTO>>()
 
 
//技巧示例:这个用法必学通过规则映射DTO
 public class TreeDTO
 {
      public int Id { getset; }
      public string Name { getset; }
      public int ParentId { getset; }
      public string ParentName { getset; }//对应Parent中的Name
 }
public class Tree
 {
    [SqlSugar.SugarColumn(IsPrimaryKey = true)]
     public int Id { getset; }
     public string Name { getset; }
     public int ParentId { getset; }
     [Navigate(NavigateType.OneToOne,nameof(ParentId))]
     public Tree Parent { getset; } 
}
         
 var list= db.Queryable<Tree>()
                .Includes(it => it.Parent) 
                .ToList();
 //DTO和List不能是同一个类不然这种映射会失效
 var dtolist= list.Adapt<List<TreeDTO>>();//DTO中的ParentName就有值了

2. 手动转DTO   升级: 5.1.4.71

老版本注意:是Select中用导航对象

//简单的用法   5.1.4.71
var list = db.Queryable<Student_004>()
        .Includes(x => x.books)
        .Select(x => new Student_004DTO
           {
             books = x.books 
              
            }, true)//true是自动映射其他属性,匿名对象需要手动
           .ToList();
                  
                 
//Mapster转换  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>>() //导航对象用 Mapster转换 (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, 
                   //导航对象books可以是C#任何方法结尾
                   bookIds=x.books.Select(it=>it.id).ToList(), 
                   booksDto=x.books.Select(it=>new BookDTO()
                                       {  id=it.Id,
                                           Name=it.Name  
                                          }).ToList()
                 })
                .ToList();   
 
//联表查询用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();

2.8 导航方法

一对多和多对多

在我们一对多和多对多对象我们可以用导航方法Any()和导航方法Count

//注意:不需 Includes 就可以使用
Where(it=>it.导航对象.Any())
Where(it=>it.导航对象.Any(z=>z.id==1))
Where(it=>it..导航对象.Any(List<IConditionalModel>)//5.1 
 
//Count用法类似

一对一函数  5.1.2.9

//注意:不需 Includes 就可以使用
Where(x=>SqlFunc.Exists(x.SchoolA.Id))//查询存在一对一的主表数据
Where(x=>SqlFunc.Exists(x.SchoolA.Id,List<IConditionalModel>))//查询存在一对一的主表数据

2.9  Root->books->[A,B]

如果Books下面有2个导航A和B

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

2.91 跨库导航

https://www.donet5.com/Home/Doc?typeId=2244

3、支持联表的导航

手动映射适合没有主键或者复杂的一些操作,该功能和Includes文档 2.4比较接近

3.1 创建测试数据

创建类

public class StudentA
{
    [SugarColumn(IsPrimaryKey = true)]
    public int StudentId { getset; }
    public string Name { getset; }
    public int SchoolId { getset; }
    [SugarColumn(IsIgnore = true)]
    public SchoolA SchoolA { getset; }
}
 
public class SchoolA
{
    [SugarColumn(IsPrimaryKey = true)]
    public int SchoolId { getset; }
    public string SchoolName { getset; }
    [SugarColumn(IsIgnore = true)]
    public List<RoomA> RoomList { getset; }
    [SugarColumn(IsIgnore = true)]
    public List<TeacherA> TeacherList { getset; }
}
public class TeacherA
{
    [SugarColumn(IsPrimaryKey = true)]
    public int Id { getset; }
    public int SchoolId { getset; }
    public string Name { getset; }
}
public class RoomA
{
    [SugarColumn(IsPrimaryKey = true)]
    public int RoomId { getset; }
    public string RoomName { getset; }
    public int SchoolId { getset; }
}

创建测试数据

db.CodeFirst.InitTables<StudentA, RoomA, SchoolA,TeacherA>();
db.DbMaintenance.TruncateTable<StudentA>();
db.DbMaintenance.TruncateTable<RoomA>();
db.DbMaintenance.TruncateTable<SchoolA>();
db.DbMaintenance.TruncateTable<TeacherA>();
db.Insertable(new RoomA() { RoomId = 1, RoomName = "北大001室", SchoolId = 1 }).ExecuteCommand();
db.Insertable(new RoomA() { RoomId = 2, RoomName = "北大002室", SchoolId = 1 }).ExecuteCommand();
db.Insertable(new RoomA() { RoomId = 3, RoomName = "北大003室", SchoolId = 1 }).ExecuteCommand();
db.Insertable(new RoomA() { RoomId = 4, RoomName = "清华001厅", SchoolId = 2 }).ExecuteCommand();
db.Insertable(new RoomA() { RoomId = 5, RoomName = "清华002厅", SchoolId = 2 }).ExecuteCommand();
db.Insertable(new RoomA() { RoomId = 6, RoomName = "清华003厅", SchoolId = 2 }).ExecuteCommand();
 
 
db.Insertable(new SchoolA() { SchoolId = 1, SchoolName = "北大" }).ExecuteCommand();
db.Insertable(new SchoolA() { SchoolId = 2, SchoolName = "清华" }).ExecuteCommand();
 
db.Insertable(new StudentA() { StudentId = 1, SchoolId = 1, Name = "北大jack" }).ExecuteCommand();
db.Insertable(new StudentA() { StudentId = 2, SchoolId = 1, Name = "北大tom" }).ExecuteCommand();
db.Insertable(new StudentA() { StudentId = 3, SchoolId = 2, Name = "清华jack" }).ExecuteCommand();
db.Insertable(new StudentA() { StudentId = 4, SchoolId = 2, Name = "清华tom" }).ExecuteCommand();
 
db.Insertable(new TeacherA() {  SchoolId=1, Id=1, Name="北大老师01" }).ExecuteCommand();
db.Insertable(new TeacherA() { SchoolId = 1, Id =2, Name = "北大老师02" }).ExecuteCommand();
 
db.Insertable(new TeacherA() { SchoolId = 2, Id = 3, Name = "清华老师01" }).ExecuteCommand();
db.Insertable(new TeacherA() { SchoolId = 2, Id = 4, Name = "清华老师02" }).ExecuteCommand();

3.2 手动实现二层

注意:普通导航看标题2 ,ThenMapper是用来处理 普通导航不能实现的功能

结构:  Student->SchoolA

var list = db.Queryable<StudentA>().ToList();//这儿也可以联表查询
db.ThenMapper(list, stu =>
{
  //如果加Where不能带有stu参数,stu参数写到 SetContext
  //可以用Where写SetContext但是不能带有stu对象
  stu.SchoolA=db.Queryable<SchoolA>().SetContext(scl=>scl.SchoolId,()=>stu.SchoolId,stu).FirstOrDefault();
   
  //可以联查询的
  //stu.xxxx=db.Queryable<SchoolA>().LeftJoin<XXX>().Select(xxxx).SetContext(....).ToList();
});
// SetContext不会生成循环操作,高性能  和直接Where性能是不一样的

注意:1、如果没有SetContext那么这个查询将会循环

2、db.ConextId外面和里面需要是同一个

3.3 联表导航多层级

注意:普通导航看标题2,ThenMapper是用来处理 普通导航不能实现的功能

了解原理后我们用ThenMapper想映射哪层就映射哪层

var treeRoot=db.Queryable<Tree>().Where(it => it.Id == 1).ToList();
//第一层
db.ThenMapper(treeRoot, item =>
{
    item.Child = db.Queryable<Tree>().SetContext(x => x.ParentId, () => item.Id, item).ToList();
});
//第二层
db.ThenMapper(treeRoot.SelectMany(it=>it.Child), it =>
{
    it.Child = db.Queryable<Tree>().SetContext(x => x.ParentId, () => it.Id, it).ToList();
});
//第三层
db.ThenMapper(treeRoot.SelectMany(it => it.Child).SelectMany(it=>it.Child), it =>
{
    it.Child = db.Queryable<Tree>().SetContext(x => x.ParentId, () => it.Id, it).ToList();
});
//这儿只是用树型结构来证明可以实现无限级别导航查询 ,实际开发中树型结构用ToTree实现
public class Tree
{
[SqlSugar.SugarColumn(IsPrimaryKey =true)]
public int Id { getset; }
public string Name { getset; }
public int ParentId { getset; }
[SqlSugar.SugarColumn(IsIgnore = true)]
public Tree Parent { getset; }
[SqlSugar.SugarColumn(IsIgnore = true)]
public List<Tree> Child { getset; }
}
// SetContext不会生成循环操作,高性能  和直接Where性能是不一样的

新功能 : 请升级到5.0.6.7 预览版本 及以上

4、树型查询

https://www.donet5.com/Home/Doc?typeId=2311

5、老版导航查询

如果使用Mapper的用户可以看这个

https://www.donet5.com/ask/9/15831

6、不加特性使用导航

通过实体AOP方法实现,具体用法看实体配置

EntityService= (type, columnInfo) =>
{
   p.IfTable<Order>().OneToOne(it => it.Item, nameof(Order.ItemId));
}

7、自动Include 5.1.4.63

第二层的所有导航自动Include(不支持第三层和第四层)

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

可以看下图 自动导航替换了下面注释代码

注意:

第一层it下面的通过IncludesAllFirstLayer全自动

第二层(it.ProjectTransferDocs)通过IncludesAllSecondLayer半自动。三层四级需要全部手动

9、兼容EF CORE 非List<T>的导航

 vra list=db.Queryable<Order>()
               .Includes(it=>it.导航对象.ToList())//通过.ToList()转成SqlSugar导航类型就行
               .ToList();

10、泛型导航

通过鉴别器实现

var dis=db.Queryable<UnitTestDis<Cat>>()
                .Includes(x => x.Animals).ToList();//T是Cat那么就能导航Cat
                  
var dis2 = db.Queryable<UnitTestDis<Dog>>()
               .Includes(x => x.Animals).ToList();//T是Dog那么就能导航Dog

SqlSugar导航查询/多级查询的更多相关文章

  1. Hibernate_day04--课程安排_Hibernate查询方式_对象导航查询_OID查询

    Hibernate_day04 上节内容 今天内容 Hibernate查询方式 对象导航查询 OID查询 HQL查询 查询所有 条件查询 排序查询 分页查询 投影查询 聚集函数使用 QBC查询 查询所 ...

  2. 基于jquery的可查询多级select控件(可记录历史选择)

    一.功能和使用 公司有功能需求,还要一条代码引入的控件,网上找完全符合的控件比较难,寻找所花的时间还不如自己写一个,所以找个空闲时间自己写了一个   控件功能:1.可手动输入查询,也可点击下拉框查询, ...

  3. Hibernate 笔记 HQL查询 条件查询,聚集函数,子查询,导航查询

    在hibernate中进行多表查询,每个表中各取几个字段,也就是说查询出来的结果集并没有一个实体类与之对应,如何解决这个问题? 解决方案一,按照Object[]数据取出数据,然后自己组bean 解决方 ...

  4. 关系数据库SQL之基本数据查询:子查询、分组查询、模糊查询

    前言 上一篇关系数据库常用SQL语句语法大全主要是关系型数据库大体结构,本文细说一下关系型数据库查询的SQL语法. 语法回顾 SELECT [ALL|DISTINCT] <目标列表达式>[ ...

  5. 【知识库】-数据库_MySQL之基本数据查询:子查询、分组查询、模糊查询

    简书作者:seay 文章出处: 关系数据库SQL之基本数据查询:子查询.分组查询.模糊查询 回顾:[知识库]-数据库_MySQL常用SQL语句语法大全示例 Learn [已经过测试校验] 一.简单查询 ...

  6. Linq to SQL 语法查询(链接查询,子查询 & in操作 & join,分组统计等)

    Linq to SQL 语法查询(链接查询,子查询 & in操作 & join,分组统计等) 子查询 描述:查询订单数超过5的顾客信息 查询句法: var 子查询 = from c i ...

  7. Thinkphp查询 1.查询方式 2.表达式查询 3.快捷查询 4.区间查询 5.组合查询 6.统计查询 7.动态查询 8.SQL 查询

    1.使用字符串作为条件查询 $user = M('User'); var_dump($user->where('id=1 AND user="蜡笔小新"')->sele ...

  8. HQL查询——HQL查询的基本用法

    HQL查询--HQL查询的基本用法 1.HQL语法类似于SQL语法,但是需要注意的是,HQL是一种完全面向对象的查询语言.SQL语言操作的对象是数据表.列等数据库对象,而HQL语言的操作对象是类.实例 ...

  9. MySQL数据库6 -查询基础,简单查询,条件查询,对查询结果排序

    一.SELECT语句 SELECT COL1,COL2,....COLn FROM TABLE1,TABLE2,....TABLEn [WHERE CONDITIONS] -- 查询条件 [GROUP ...

  10. LinQ实战学习笔记(三) 序列,查询操作符,查询表达式,表达式树

    序列 延迟查询执行 查询操作符 查询表达式 表达式树 (一) 序列 先上一段代码, 这段代码使用扩展方法实现下面的要求: 取进程列表,进行过滤(取大于10M的进程) 列表进行排序(按内存占用) 只保留 ...

随机推荐

  1. 容器卡在terminate状态无法删除

    1. pod卡在terminate状态无法删除.一般是lxcfx 卡住 或者 logcounter组件进程读容器数据盘分区导致的 2.  验证一下我们的猜测 cat /sys/fs/fuse/conn ...

  2. 【辅助工具】Postman使用

    Postman使用 批量处理 https://www.bbsmax.com/A/A7zglyjoJ4/ pm.test("测试结果成功", function () {     pm ...

  3. 如何在CSDN上如何快速转载博客

    复制粘贴应该是最显而易见的方法,但是不仅会有丢失内容,而且格式也会丢失.要想达到更好的效果,可以从html源码入手. 1.在chrome浏览器中打开要转载的文章,右键选择检查(or使用F12) 2.在 ...

  4. 【调试】kdump原理及其使用方法

    kdump机制 简介 Kdump是在系统崩溃.死锁或死机时用来转储内存运行参数的一个工具和服务,是一种新的crash dump捕获机制,用来捕获kernel crash(内核崩溃)的时候产生的cras ...

  5. 《深入理解计算机系统》(CSAPP)读书笔记 —— 第七章 链接

    链接( Clinking)是将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载(复制)到内存并执行.链接可以执行于编译时( compile time),也就是在源代码被翻译成机器代 ...

  6. C#设计模式18——迭代器模式的写法

    是什么: 迭代器模式是一种行为型设计模式,它允许客户端通过一种统一的方式遍历集合对象中的元素,而无需暴露集合对象的内部结构. 为什么: 使用迭代器模式可以使得客户端程序与集合对象解耦,从而可以更加灵活 ...

  7. Apache ShardingSphere 实现分库分表及读写分离

    本文为博主原创,未经允许不得转载: 项目demo 源码地址:https://gitee.com/xiangbaxiang/apache-shardingjdbc 1. 创建Maven项目,并配置 po ...

  8. springBoot 整合 hikari

    Hikari是一款非常强大,高效,并且号称"史上最快连接池".并且在springboot2.0之后,采用的默认数据库连接池就是Hikari.不需要引入依赖,已经在SpringBoo ...

  9. Python毕业设计推荐

    今天给大家推荐几个基于python/django的毕业设计/课程设计. 1. 网上商城系统 这是一个基于python+vue开发的商城网站,平台采用B/S结构,后端采用主流的Python语言进行开发, ...

  10. Angular系列教程之管道

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...