跨库查询、多库查询

一、跨库导航 (5.1.3.24

优点1:支持跨服务器,支持跨数据库品种, 支持任何类型数据库 

优点2:   超级强大的性能,能达到本库联表性能

缺点:不支持子表过滤主表 (方案有ToList后在内存过滤, 如果分页可以查前1000条主表在内存分页 前端只显示前10页)

[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; }
 }
 
//通过ConfigId进行区分是哪个库
var db = new SqlSugarClient(new List<ConnectionConfig>()
{
  new ConnectionConfig(){ConfigId="db1",DbType=DbType.Sqlite,
  ConnectionString="DataSource=/Db_OrderDb.sqlite",IsAutoCloseConnection=true},
  
  new ConnectionConfig(){ConfigId="db2",DbType=DbType.Sqlite,
  ConnectionString="DataSource=/Db_OrderItemDb.sqlite",IsAutoCloseConnection=true }
});
 
//通过实体类特性Tenant自动映射不同数据库进行查询
var list=db.QueryableWithAttr<OrderItem>()
.Includes(z => z.Order)
.ToList(); //1行代码就搞定了2个库联表查询

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

详细教程 (5.1.3.25)

https://www.cnblogs.com/sunkaixuan/p/16767798.html


二、普通跨库查询

优点:联表语法100%可以用

缺点:只支持个别数据库,并且跨服务器比较麻烦需要配置dblink

大多数的数据库支持下面的写法,我们可以通过As指定是哪个库, 查询的时候用别名

注意:不同数据库写法有区别 下面是SqlServer例子 : 库名.dbo.表名

//单表跨库
var  list=db.Queryable<Order>().AS("xx.dbo.Order2019").ToList();



//新版本:多表跨库
var list1 = db.Queryable<Order>().AS("xx.dbo.order")  //如果跨服务器需要配置dblink,语法上每种数据库有点小差异
        .LeftJoin<OrderItem>((o,i)=> o.Id == i.OrderId,"yy.dbo.OrderItem")  
        .LeftJoin<Custom>((o, i, c) => c.Id == o.CustomId,"zz.dbo.Custom") 
        .Select((o,i,c)=>new classA() { oid=o.Id , iname=i.Name })
        .ToList();


//老版本:多表跨库
var list1 = db.Queryable<Order>().AS("xx.dbo.order") // AS("")
        .LeftJoin<OrderItem>((o,i)=> o.Id == i.OrderId).AS<OrderItem>("yy.dbo.OrderItem") //AS<T>
        .LeftJoin<Custom>((o, i, c) => c.Id == o.CustomId) .AS<Custom>("zz.dbo.Custom")//AS<T>
        .Select((o,i,c)=>new classA() { oid=o.Id , iname=i.Name })
        .ToList();
 //获取表名可以减少字符串操作
  var tableName=db.EntityMaintenance.GetTableName<T>()       
 //如果有2个AS<T>是相同我们可以这么写
 .LeftJoin(db.Queryable<T>().AS("xx.dbo.zzzz"),(o,i)=>o.id==i.id)


三、自动跨库查询(同服务器)

注意:

1.只支持MySql和SqlServer同服务器并且是同一种类型的库(你有办法支持其他库可以反馈给我)

2.查询用的是QueryableWithAttr不是Queryable

//声名SqlSugar对象
var db = new SqlSugarClient(new List<ConnectionConfig>()
{
 new ConnectionConfig(){ConfigId="A",DbType=DbType.SqlServer,ConnectionString=..,IsAutoCloseConnection=true},
 new ConnectionConfig(){ConfigId="B",DbType=DbType.MySql,ConnectionString=..,IsAutoCloseConnection=true  },
 new ConnectionConfig(){ConfigId="C",DbType=DbType.MySql,ConnectionString=..,IsAutoCloseConnection=true  }
});

//实体配置是哪个库
[Tenant("A")] //实体标为A表示是A库
public class OrderItem
  
//联表查询要5.1.4.66+才支持
var list1 = db.QueryableWithAttr<Order>() //根根据ConfigId自动实现跨库
        .LeftJoin<OrderItem>((o,i)=> o.Id == i.OrderId)  
        .LeftJoin<Custom>((o, i, c) => c.Id == o.CustomId) 
        .Select((o,i,c)=>new classA() { oid=o.Id , iname=i.Name })
        .ToList();

像PGSQL ORACLE 等看标题4


四、自动跨服务器配置(可以跨库)

除了sqlite,其他的应该都支持dblink配置,只要能配置dblink就能跨库查询

用例

请升级5.1.4.72-preview02+

var db = new SqlSugarClient(new List<ConnectionConfig>()
{
 new ConnectionConfig(){ConfigId="A",DbType=DbType.SqlServer,ConnectionString=..,IsAutoCloseConnection=true  },
 new ConnectionConfig(){
                          ConfigId="B",
                          DbType=DbType.SqlServer,
                          DbLinkName="db1.ecology2013_SHQC2.dbo",//配置dblink库名
                          ConnectionString=..,IsAutoCloseConnection=true  }
});
//实体配置是哪个库
[Tenant("B")] //实体标为A表示是A库
public class OrderItem
   
//联表查询要5.1.4.66+才支持
var list1 = db.QueryableWithAttr<Order>() //根根据ConfigId自动实现跨库
        .LeftJoin<OrderItem>((o,i)=> o.Id == i.OrderId)  
        .ToList();
//生成Sql        
//Left join db1.ecology2013_SHQC2.dbo.OrderItem

配置dblink

下面是SqlServer的例子

可以企业管理器里添加linkserver实现。

使用sp_addlinkedserver创建一个链接的服务器,使其允许对分布式的、针对 OLEDB 数据源的异类查询进行访问。

在使用 sp_addlinkedserver 创建链接的服务器之后,此服务器就可以执行分布式查询。

步骤:

1. 创建linkserver

 EXEC sp_addlinkedserver

 @server='DB1',--被访问的服务器别名

 @srvproduct='', --sqlserver不需要指定

 @provider='SQLOLEDB',

5@datasrc='192.168.1.102' --要访问的服务器

2. 登录链接服务器

EXEC sp_addlinkedsrvlogin 

 'DB1', --被访问的服务器别名

 'false', --useself

 NULL, --locallogin

'sa', --帐号 

'123456' --密码

 

文档:SqlSugar5.0