前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C# 动态创建类,动态创建表,支持多库的数据库维护方案

C# 动态创建类,动态创建表,支持多库的数据库维护方案

原创
作者头像
软件架构师Michael
发布2023-10-22 11:16:04
5160
发布2023-10-22 11:16:04
举报

一、创建表

SqlSugar支持了3种模式的建表(无实体建表、实体建表,实体特性建表),非常的灵活

可以多个数据库 MYSQL MSSQL ORACLE SQLITE PGSQL 等用同一语法创建数据库,最近TDengine,达梦和高斯等国产数据库也都实现了支持。可谓可圈可点。不需要考虑数据库的兼容性。

1.1、通过特性建表

我们可以通过创建实体来进行建表

代码语言:javascript
复制
public class CodeFirstTable1
{
        [SugarColumn(IsIdentity = true, IsPrimaryKey = true)]
        public int Id { get; set; }
        public string Name { get; set; }
        //ColumnDataType 自定格式的情况 length不要设置 (想要多库兼容看4.2和9)
        [SugarColumn(ColumnDataType = "Nvarchar(255)")]
        public string Text { get; set; }
        [SugarColumn(IsNullable = true)]//可以为NULL
        public DateTime CreateTime { get; set; }
}
  
/***创建单个表***/
db.CodeFirst.SetStringDefaultLength(200).InitTables(typeof(CodeFirstTable1));//这样一个表就能成功创建了
/***手动建多个表***/
db.CodeFirst.SetStringDefaultLength(200)
.InitTables(typeof(CodeFirstTable1),typeof(CodeFirstTable2));

建表特性如下

2.2、无特性建表

如果我们的实体不需要加特性,那么我们可以通过无特性方式建表

代码语言:javascript
复制
SugarClient db = new SqlSugarClient(new ConnectionConfig()
{
    DbType = DbType.SqlServer,
    ConnectionString = Config.ConnectionString3,
    InitKeyType = InitKeyType.Attribute,
    IsAutoCloseConnection = true,
    ConfigureExternalServices = new ConfigureExternalServices()
    {
        EntityService = (s, p) =>
        {
            //如果是Order实体进行相关配置
            p.IfTable<Order>()
            .UpdateProperty(it => it.id, it =>
            {
                it.IsIdentity = true;
                it.IsPrimarykey = true;
            })
            .UpdateProperty(it => it.Name, it => {
                it.Length = 100;
                it.IsNullable = true;
   
            })
            .OneToOne(it => it.Item, nameof(Order.ItemId));
               
            //如果Custom实体进行相关配置
             p.IfTable<Custom>()
             .UpdateProperty(it => it.id, it =>
             {
                it.IsIdentity = true;
                it.IsPrimarykey = true;
             })
              .UpdateProperty(it => it.Text, it => {
                it.DataType= StaticConfig.CodeFirst_BigString;//支持多库的MaxString用法
              })
               
                           
            //可以结合全局逻辑一起使用,下面的和上面的有冲突的话,下面会覆盖上面的
                
               
            //统一设置 nullable等于isnullable=true
            //低版本C#看标题2.2
             if(p.IsPrimaryKey==false&&new NullabilityInfoContext()
                         .Create(c).WriteState is NullabilityState.Nullable)
             {
                           p.IsNullable = true;
             }
               
                
                
        }
    }
});
//性能说明:
//EntityService 相同实体只会执行一次性不需太操作
1.3、无实体建表

功能与实体建类一模一样,如果使用SqlSugar中间标准,可以支持多个数据库一套代码建表

代码语言:javascript
复制
var type = db.DynamicBuilder().CreateClass("UnitEntityA",
               new SugarTable()
               {
                   TableDescription = "表备注",
                   //DisabledUpdateAll=true 可以禁止更新只创建
               }
           )
          .CreateProperty("Id", typeof(int), new SugarColumn() { IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "列备注" })
          .CreateProperty("Name", typeof(string), new SugarColumn() {Length=200, ColumnDescription = "列备注" })
          .BuilderType();
 
           db.CodeFirst.InitTables(type);

二、数据库维护

SqlSugar有一套数据库维护API,并且能够很好的支持多种数据库,例如备份数据库等常用功能

代码语言:javascript
复制
//例1 获取所有表
var tables = db.DbMaintenance.GetTableInfoList(false);//true 走缓存 false不走缓存
foreach (var table in tables)
{
     Console.WriteLine(table.Description);//输出表信息
       
     //获取列信息
     //var columns=db.DbMaintenance.GetColumnInfosByTableName("表名",false);
}
  
//例2
db.DbMaintenance.IsAnyTable("tablename",false)//验证表名是否缓存不走缓存

所有API,更细节的内容可以参考SqlSugar官网。

三、跨库支持

可以自动识别在哪个库

实体

代码语言:javascript
复制
[TenantAttribute("1")]//对应ConfigId
public class C1Table
{
   public string Id { get; set; }
}
   
[TenantAttribute("2")]
public class C2Table
{
    public string Id { get; set; }
}
查询
代码语言:javascript
复制
//通过ConfigId进行数据库区分
var db = new SqlSugarClient(new List<ConnectionConfig>()
{
 //这儿声名所有上下文都生效
 new ConnectionConfig(){ConfigId="0",DbType=DbType.SqlServer,ConnectionString=..,IsAutoCloseConnection=true},
 new ConnectionConfig(){ConfigId="1",DbType=DbType.MySql,ConnectionString=..,IsAutoCloseConnection=true  }
});
//自动跨库联表查询
var query5 = db.QueryableWithAttr<Order>()//如果MySql和SqlServer自动支持同服务器的跨库联表查询
         .LeftJoin<Custom>   ((o, cus ) => o.CustomId == cus.Id)//多个条件用&&
         .LeftJoin<OrderDetail> ((o, cus, oritem) => o.Id == oritem.OrderId)
         .Where(o => o.Id == 1) 
         .Select((o, cus , oritem) => new ViewOrder { Id = o.Id, CustomName = cus.Name })
         .ToList(); 
//手动跨库联表查询 ,这种方式结合dblink可以跨服务器
var query5 = db.Queryable().As("xxx.表名")
         .LeftJoin<Custom>   ((o, cus ) => o.CustomId == cus.Id ,"yyyy.表名")
         .LeftJoin<OrderDetail> ((o, cus, oritem) => o.Id == oritem.OrderId ,"zzzz.名表")
         .Where(o => o.Id == 1) 
         .Select((o, cus , oritem) => new ViewOrder { Id = o.Id, CustomName = cus.Name })
         .ToList();

四、过滤器

SqlSugar支持了全新的过滤器,可以是接口,集成该接口的类都生效,支持多表查询

代码语言:javascript
复制
db.QueryFilter
.AddTableFilter<IDeletedFilter>(it => it.IsDeleted==false)//IDeletedFilter是自定义接口,继承这个接口的实体有效
.AddTableFilterIF<ITenantFilter>(isAdmint==false,it=>it.OrgId==用户OrgId);//ITenantFilter自定义接口
  
//用例1:单条语句清空,只影响当前语句
db.Queryable<Order>().ClearFilter().ToList();//所有过滤器都无效
db.Queryable<Order>().ClearFilter<IDeletedFilter>().ToList();//只有IDeletedFilter过滤器无效
db.Queryable<Order>().ClearFilter<IDeletedFilter,ITenantFilter>().ToList();//IDeletedFilter+ITenantFilter无效
    
//用例2:当前上下文清空 ,不会影响其他请求,只是当前请求清空
db.QueryFilter.Clear();
db.QueryFilter.Clear<IDeletedFilter>();
  
//用例3:清空并还原 ,不会影响其他请求,只是当前请求清空
db.QueryFilter.ClearAndBackup();//有多个重载 ClearAndBackup<T,T2>();
db.Queryable<Order>().ToList();
db.QueryFilter.Restore();//还原过滤器 (适合下面代码还需要过滤器情况)

五、子查询升级

1、ToList() 可以直接查询一个对象

2、First() 可以直接查单个对象

3、ToList(it=>it.Id) 可以查List< int >一个字段集合

4、SelectStringJoin(z => z.Name, ",") 子查询将一列用逗号拼接成字符串

代码语言:javascript
复制
var list=db.Queryable< Order >()
.Select(it => new
        {
          CustomId = it.CustomId,
          OrderId = it.Id,
          OrderName = it.Name,
          CustomList = SqlFunc.Subqueryable< Custom >().Where(c => c.Id == it.CustomId).ToList()
        })
       .ToList();

六、自定义类型支持

自定义类型转换器

下面只是讲解怎么定义转换器,ORM自带的功能就包含下面功能,只是用来讲解

代码语言:javascript
复制
public class DictionaryConvert : ISugarDataConverter
{
public SugarParameter ParameterConverter<T>(object value, int i)
{
//该功能ORM自带的IsJson就能实现这里只是用这个用例来给大家学习
var name = "@myp" + i;
var str = new SerializeService().SerializeObject(value);
return new SugarParameter(name, str);
}
 
public T QueryConverter<T>(IDataRecord dr, int i)
{
//打断点调试
//该功能ORM自带的IsJson就能实现这里只是用这个用例来给大家学习
var str = dr.GetValue(i) + "";
return new SerializeService().DeserializeObject<T>(str);
}
}
//使用自定义转换器
[SugarColumn(ColumnDataType="varchar(2000)",SqlParameterDbType=typeof(DictionaryConvert))]
public Dictionary<string, object> DcValue { get; set; }//5.1.3.53-preview08 

总结

SqlSugar在2021年到2022年大量的开源应用使用了SqlSugar,带动了SqlSugar的快速发展。

【日拱一卒,必有所获!】

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1、通过特性建表
  • 2.2、无特性建表
  • 1.3、无实体建表
  • 二、数据库维护
    • 查询
    • 五、子查询升级
    • 六、自定义类型支持
    • 自定义类型转换器
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档