配置查询

解决问题:

1、大量用到多表查询 ,只为一个Name就进行联表

2、字典表的联表查询,字典表我相信大家都全用到,他们可以方便的存储性别、学历、岗位等 一串数据 并进行TypeId进行区分


老功能 配置查询

1.1 创建测试数据

创建一个字典实体

public class DataDictionary
{
    public string Code { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
}

创建字典表并向里面插入测试数据  

var db = GetInstance();
            List<DataDictionary> datas = new List<DataDictionary>();
            datas.Add(new DataDictionary() { Code="1", Name="男",Type="sex" });
            datas.Add(new DataDictionary() { Code = "2", Name = "女", Type = "sex" });
            datas.Add(new DataDictionary() { Code = "1", Name = "南通市", Type = "city" });
            datas.Add(new DataDictionary() { Code = "2", Name = "苏州市", Type = "city" });
            datas.Add(new DataDictionary() { Code = "1", Name = "江苏省", Type = "province" });
            datas.Add(new DataDictionary() { Code = "2", Name = "湖南省", Type = "province" });
            db.Insertable(datas).ExecuteCommand();//这样就能把数据插进数据库了

在建一个Person表  

public class Person
{
    //数据库字段
    [SqlSugar.SugarColumn(IsPrimaryKey =true,IsIdentity =true)]
    public int Id { get; set; }
    public string Name { get; set; }
    public int SexId { get; set; }
    public int CityId { get; set; }
    public int ProvinceId { get; set; }
 
    //非数据库字段
    [SqlSugar.SugarColumn(IsIgnore =true)]
    public string SexName { get; set; }
    [SqlSugar.SugarColumn(IsIgnore = true)]
    public string CityName { get; set; }
    [SqlSugar.SugarColumn(IsIgnore = true)]
    public string ProvinceName { get; set; }
} 

1.2 传统实现缺点

如果我们要将Person中的非数据字段查询出来那么我们就需要写有2种实现方式

1.连表或者子查询 (缺点 写起来很浪费时间)

2.将字典存到内存,通过内存赋值 (缺点 字典表超过1000条以上性能很差 ,并且不能排序,或者LIKE)

1.3 使用配置查询

配置字典表

  var types= db.Queryable<DataDictionary>().Select(it => it.Type).Distinct().ToList();
   //上面有耗时操作写在Any上面,保证程序启动后只执行一次
   if (!db.ConfigQuery.Any()) 
   { 
      foreach (var type in types)
      {
       db.ConfigQuery.SetTable<DataDictionary>(it =>it.Code,it =>it.Name,type,it =>it.Type==type);
      }
    }
      //像姓别是01 02 学历也是01 02 这种只能按这种循环方式,需要加个Type区分唯一
      //如果其中Code都是唯一值可以按1.4中的用法使用 ,一行代码就可以配置不需要循环
      //如果你认为麻烦你也可以把这个配置扔到程序启动中完成

配置完我们查询就会很方便了

   var res=db.Queryable<Person>().Select(it => new Person()
   {
         Id=it.Id.SelectAll(),  // Oracle 注意:单表查询要设置别名SelectAll("别名")
         SexName=it.SexId.GetConfigValue<DataDictionary>("sex"),
         ProvinceName = it.ProvinceId.GetConfigValue<DataDictionary>("province"),
         CityName = it.CityId.GetConfigValue<DataDictionary>("city"),
   }).ToList();
   //生成的Sql
   //select  *,
   //          (select name from  DataDictionary  where type='sex' where t.code=sexid) as sexname,
   //          (select name from  DataDictionary  where type='city'where t.code=cityid) as cityname,   
   //          (select name from  DataDictionary  where type='province' where t.code=provinceid) as provincename 
   // from Person t      
   //支持写在Where或者Orderby 

1.4 简单联表查询也可以配置

//配置Order 
if (!db.ConfigQuery.Any()) //保证只配置一次不能更新,该配置是全局静态存储
{
 db.ConfigQuery.SetTable<Order>(it => it.Id, it => it.Name);
 //多个配置可以一起写在下面
}
//使用
var list3 = db.Queryable<OrderItem>().Select(it => new OrderItem
{
        ItemId = it.ItemId.SelectAll(), // Oracle 注意:单表查询要设置别名SelectAll("别名")
        OrderName = it.OrderId.GetConfigValue<Order>() //查询的时候直接用
}).ToList();
//select *,
//     (select name from order where id= t.orderid) as ordername 
//from orderitem t

 总结:配置表查询的方式可以大大降低重复联表问题,并且配置好后基本就不要写JOIN了 

1.5 参数介绍

SetTable<T> 总共4个参数 ,T 代表哪个实体表

参数 1、主键或者关联字段

参数 2、显示的文本

参数 3、唯一标识(可不填) 当一个T对应多个查询的时候需要指定一个唯一标识

参数 4、查询条件(可不填


新功能 字典导航

请求升 5.1.2-preview

通过导航查询我们也可以实现配置查询

优点:支持多层级一对一 

不足:  像字典表没办法动态配置,依赖主键和导航配置

[SugarTable("UnitDataMain")]
public class DataMain 
{
    //表属性   
    public int Id{get;set;}
    public string Name{get;set;}
    public string SexCode { get; set; }
    public  string Province { get; set; }
    
    
    //导航
    [SqlSugar.Navigate(NavigateType.OneToOne,nameof(SexCode),nameof(DataDictionary1.Code),"type='sex'")]
    public DataDictionary1 SexInfo { get; set; }

    [SqlSugar.Navigate(NavigateType.OneToOne, nameof(Province), nameof(DataDictionary1.Code), "type='province'")]
    public DataDictionary1 ProvinceInfo { get; set; }
}


var list=db.Queryable<DataMain>()
        .Includes(x => x.SexInfo)
        .Includes(x => x.ProvinceInfo)
        .ToList();//返回导航属性
        
        //联表导航
var list2 = db.Queryable<DataMain>()
        .Where(x=>x.SexInfo.Name=="男")//也可以在Select用
        .ToList();


文档:SqlSugar5.0