【愚公系列】2023年01月 .NET CORE工具案例-基于SqlSugar的多库多表融合查询

举报
愚公搬代码 发表于 2023/01/31 21:40:17 2023/01/31
【摘要】 前言SqlSugar 是一款 老牌 .NET 开源ORM框架,由果糖大数据科技团队维护和更新 ,开箱即用,最易上手的ORM框架 ,51Job和Boss直招简历数超过国外框架 Nhibernate PetaPoco, 仅次于Dapper和EF Core , 占Dapper 40% 。一般比较大型复杂的系统都会遇到如下问题:多库查询:比如 MYSQL和一个SQLSERVER进行联表查询 ,或者...

前言

SqlSugar 是一款 老牌 .NET 开源ORM框架,由果糖大数据科技团队维护和更新 ,开箱即用,最易上手的ORM框架 ,51Job和Boss直招简历数超过国外框架 Nhibernate PetaPoco, 仅次于Dapper和EF Core , 占Dapper 40% 。

一般比较大型复杂的系统都会遇到如下问题:

  • 多库查询:比如 MYSQL和一个SQLSERVER进行联表查询 ,或者SQLITE和MYSQL进行联表查询
  • 多服务器查询:A服务器和B服务器查询

SqlSugar其实是可以支持以上2种的,下面来着重介绍SqlSugar多库多表融合查询

SqlSugar官网:https://www.donet5.com/Doc/1/1226

在这里插入图片描述

一、基于SqlSugar的多库多表融合查询

多库多表查询架构图如下:
在这里插入图片描述

1.安装包

SqlSugarCore

在这里插入图片描述

2.订单表

[Tenant("db2")] //实体标为db2
public class OrderItem
{
           [SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
           public int ItemId { get; set; }
           public int OrderId { get; set; }
           public decimal? Price { get; set; }
           [SqlSugar.SugarColumn(IsNullable = true)]
           public DateTime? CreateTime { get; set; }
           [Navigate(NavigateType.OneToOne,nameof(OrderId))] //设置关系 对应Order表主键
           public Order Order { get; set; }
}
[Tenant("db1")] //实体标为db1
public class Order
{
          [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
          public int Id { get; set; }
          public string Name { get; set; }
          public decimal Price { get; set; }
          [SugarColumn(IsNullable = true)]
          public DateTime CreateTime { get; set; }
          [SugarColumn(IsNullable = true)]
          public int CustomId { get; set; }
          [Navigate(NavigateType.OneToMany, nameof(OrderItem.OrderId))]//
          public List<OrderItem> Items { get; set; }
}

在这里插入图片描述
在这里插入图片描述

3.添加连接

3.1 初始化添加

var db = new SqlSugarClient(new List<ConnectionConfig>()
{
  new ConnectionConfig(){ConfigId="db1",DbType=DbType.MySql,
  ConnectionString="Server=localhost;Database=test;Uid=root;Pwd=123456;",IsAutoCloseConnection=true},

  new ConnectionConfig(){ConfigId="db2",DbType=DbType.SqlServer,
  ConnectionString="Server=localhost;User=sa;Password=1;Database=test;Encrypt=True;TrustServerCertificate=True;",IsAutoCloseConnection=true }
});

3.2 动态添加

if(!db.IsAnyConnection(configId))//当前上下文不存在则添加
    db.AddConnection(new ConnectionConfig{
                           DbType = DbType.SqlServer,ConfigId = "1",
                IsAutoCloseConnection = true,
                ConnectionString = 。。});

4.查询

4.1 子表对主表(一对一)查询

1、通过Tenant自动映射

//通过实体类特性Tenant自动映射不同数据库进行查询
var list=db.QueryableWithAttr<OrderItem>()
.Includes(z => z.Order)
.ToList(); //1行代码就搞定了2个库联表查询

在这里插入图片描述

2、不通过Tenant自动映射

//不通过特性实现跨库导航
var list = db.GetConnection("db2").Queryable<OrderItem>()//Orderitem是db1
               .CrossQuery(typeof(Order), "db1")//Order是db2
               .Includes(z => z.Order)
               .ToList();

在这里插入图片描述

4.2 主表对子表(一对多)查询

var list = db.QueryableWithAttr<Order>()
                   .Includes(z => z.Items)//跨库一对多
                   .ToList();

在这里插入图片描述

4.3 用户权限角色(多对多)查询

配置用户权限角色三表


var db = new SqlSugarClient(new List<ConnectionConfig>()
   {
       new ConnectionConfig(){ConfigId="A",DbType=DbType.Sqlite,ConnectionString="DataSource=/A_DB.sqlite",IsAutoCloseConnection=true},
       new ConnectionConfig(){ConfigId="B",DbType=DbType.Sqlite,ConnectionString="DataSource=/B_DB.sqlite",IsAutoCloseConnection=true  },
       new ConnectionConfig(){ConfigId="AB",DbType=DbType.Sqlite,ConnectionString="DataSource=/AB_DB.sqlite",IsAutoCloseConnection=true  }
 });p 

实体

 [Tenant("A")]//指定为A库
 public partial class OperatorInfo
 {
     /// <summary>
     /// 主键
     /// </summary>
     [SugarColumn(IsPrimaryKey = true)]
     public int id { get; set; }

     /// <summary>
     /// 姓名
     /// </summary>
     public string realname { get; set; }

     /// <summary>
     /// 多角色
     /// </summary>
     [Navigate(typeof(OptRole), nameof(OptRole.operId), nameof(OptRole.roleId))]//配置导航
     public List<Role> Roles { get; set; }
 }


 [Tenant("B")]//指定为B库
 public partial class Role
 {
     /// <summary>
     /// 角色
     /// </summary>
     [SugarColumn(IsPrimaryKey = true )]
     public int id { get; set; }

     /// <summary>
     /// 角色名称
     /// </summary>
     public string name { get; set; }

 }


 [Tenant("AB")]//指定为AB库
 public partial class OptRole
 {
     /// <summary>
     ///
     /// </summary>
     [SugarColumn(IsPrimaryKey = true)]
     public int id { get; set; }

     /// <summary>
     ///
     /// </summary>
     public int operId { get; set; }

     /// <summary>
     ///
     /// </summary>
     public int roleId { get; set; }


 }

//3个库3个表进行多对多查询
var x=db.QueryableWithAttr<OperatorInfo>()
.Includes(z => z.Roles).ToList();
//多个表联表
var x=db.QueryableWithAttr<TB>()
.Includes(z => z.A1)
.Includes(z => z.A2)
.Includes(z => z.A3).ToList();
 
//多个表嵌套联表
var x=db.QueryableWithAttr<TB>()
.Includes(z =>z.A1, z.Province,z=>z.City)//4个层级
.Includes(z => z.A2)
.Includes(z => z.A3).ToList();

8.事务

//开启事务
try
{
    //db我们称为主Db
    db.BeginTran(); //开启多库 (db.Ado.BeginTran是单库事务)事务支持单库和多库

    db.GetConnection("db1").Insertable(new Order()//var childDb=db.GetConnection(1);我们称为子DB,子DB不具有租户方法,具有单当库操作方法
    {
        CreateTime = DateTime.Now,
        CustomId = 2,
        Name = "小米10",
        Price = 1
    }).ExecuteCommand();

    db.GetConnection("db2").Insertable(new OrderItem()
    {
        CreateTime = DateTime.Now,
        OrderId = 1,
        Price = 1
    }).ExecuteCommand();

    //提交事务
    db.CommitTran();

}
catch (Exception ex)
{
    //回滚事务
    db.RollbackTran();
}

在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。