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

1、创建表

SqlSugar支持了3种模式的建表,非常的灵活,可以MYSQL MSSQL ORACLE等用同一语法创建数据库,不需要考虑数据库的兼容性

中间标准:

string 大文本

5.1.3.44-preview06 推荐

[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)]

string 设置长度的字符串

[SugarColumn(Length=10)]

public string FieldName{ get; set; }

int 整数

public int FieldName{ get; set; }

short 整数小

public short FieldName{ get; set; }

long 大数字

public long FieldName{ get; set; }

bool 真假

public bool FieldName{ get; set; }

decimal 默认

public decimal FieldName{ get; set; }

decimal 自定义

//18,2 18,4 18,6 这几种兼容性好

[SugarColumn(Length=18,DecimalDigits=2)]

public decimal FieldName{ get; set; }

DateTime 时间

public DateTime FieldName{ get; set; }

枚举 (数据库存int)

public 枚举 FieldName{ get; set; }

byte[] 二进制

public byte[] FileInfo{get;set;}

建议:升级到 SqlSugarCore 5.1.3.46-preview09 及以上

对多库支持了比较好

SqlServer特殊配置:和他库不同一般选用Nvarchar,可以使用这个配置让他和其他数据库区分(其他库是varchar)

DbType = SqlSugar.DbType.SqlServer,

ConnectionString ="字符串",

IsAutoCloseConnection =true,

MoreSettings=newConnMoreSettings() {

SqlServerCodeFirstNvarchar=true,

}

1.1通过特性建表

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

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)); 

建表特性如下

名称描述
IsIdentity是否创建自增标识
IsPrimaryKey是否创建主键标识
ColumnName创建数据库字段的名称(默认取实体类属性名称)
ColumnDataType

创建数据库字段的类型

用法1: “varchar(20)” 不需要设置长度

用法2: 不设置该参数 系统会根据C#类型自动生成相应的数据库类型

用法3: 多库兼容可以用 :看标题9

IsIgnoreORM不处理该列
ColumnDescription备注 表注释 (新版本支持XML文件)
Length长度 设成10会生成 xxx类型(10), 没括号的不设置
IsNullable是否可以为null默为false
DecimalDigits精度 如 decimal(18,2) length=18,DecimalDigits=2
OracleSequenceName设置Oracle序列,设置后该列等同于自增列
OldColumnName修改列名用,这样不会新增或者删除列
IndexGroupNameList已弃用 ,新用法看文档4.3
UniqueGroupNameList已弃用, 新用法看文档4.3

注意:有2个属性用处不同

DefaultValue

IsOnlyIgnoreInsert

DefaultValue=默认值 用来建表设置字段默认值

IsOnlyIgnoreInsert=true 插入数据时取默认值

很多情况需要2个一起使用

如果只建表不插入数据用1个

如果建表并且插入数据用2个

 2.2无特性建表

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

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中间标准可以支持多个数据库一套代码建表

 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);

  

3、数据库维护

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

//例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

GetDataBaseList获取所有数据库名称List
GetViewInfoList查询所有视图List
GetTableInfoList获取所有表,查询所有的表 (GetTableInfoList(是否缓存))List
GetColumnInfosByTableName

获取列根据表名,获取字段,字段信

息GetColumnInfosByTableName(表名,是否缓存)

List
GetIsIdentities获取自增列List
GetPrimaries获取主键List
IsAnyTable表是否存在,判断表存不存在 ( IsAny(表名,是否缓存))bool
IsAnyColumn列是否存在bool
IsPrimaryKey主键是否存在bool
IsIdentity自增是否存在bool
IsAnyConstraint约束是否存在bool
DropTable删除表bool
TruncateTable清空表bool
CreateTable

看标题 1.1,1.2,1.3

bool
AddColumn添加列bool
UpdateColumn更新列bool
AddPrimaryKey添加主键bool
DropConstraint删除约束bool
BackupDataBase备份库bool
DropColumn删除列bool
RenameColumn重命名列bool
AddDefaultValue添加默认值bool
AddTableRemark添加表描述,表注释bool
AddColumnRemark添加列描述,表注释bool
DeleteColumnRemark删除列描述,表注释bool
RenameTable重命名表bool
CreateIndex创建索引,唯一约束(唯一索引)bool
IsAnyIndex索引是否存在bool
GetIndexList获取所有索引
GetProcList获取所有存储过程

2、跨库支持

可以自动识别在哪个库

实体

 [TenantAttribute("1")]//对应ConfigId
  public class C1Table
  {
     public string Id { get; set; }
  }
    
  [TenantAttribute("2")]
  public class C2Table
  {
      public string Id { get; set; }
  }

查询

//通过ConfigId进行数据库区分
var db = new SqlSugarClient(new List<ConnectionConfig>()
{
 //这儿声名所有上下文都生效
 new ConnectionConfig(){Config,DbType=DbType.SqlServer,ConnectionString=..,IsAutoCloseConnection=true},
 new ConnectionConfig(){Config,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(); 

插入

db.InsertableWithAttr(list).Execommand()

更新

db.UpdateableWithAttr(list).Execommand()

  

删除

db.UpdateableWithAttr(list).Execommand() 

 只要实体配置了数据库,就不要考虑换库了,直接使用,并且支持事务

3、过滤器

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

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();//还原过滤器 (适合下面代码还需要过滤器情况)

4、子查询升级

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

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

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

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

 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();

  

5、自定义类型支持

5.1 自定义类型转换器

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

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 

现有类型支持

5.1 json类型

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

5.2 枚举类型

int存储:直接用就行了

public DbType DcValue { get; set; }

string存储:高版本如下写法

[SugarColumn(ColumnDataType="varchar(20)",SqlParameterDbType=typeof(EnumToStringConvert))]
public DbType DcValue { get; set; }

3.数据库独有类型支持

看左边菜单 【数据库特性】 该菜单下面有 SqlServer菜单或者MySql菜单等 , 针对不同数据库都有专门的介绍

总结

SqlSugar在2021年到2022年大量的开源应用使用了SqlSugar,带动了SqlSugar的快速发展,我这边要感谢大家

Admin.NET通用管理平台

ZrAdminNetCore 后台

管理Yi框架(Ruoyi Vue)

SimpleAdmin (new)

vboot-netmagic.net (Vue2.0)

网关采集系统(Blazor)

RuYiAdmin

CoreShop商城

Blog.Core

YuebonCore

企业级框架Furion

WebFirst腾讯

APIJSON.NETWaterCloud微服务

ViperFamilyBucket应用框架通用后台

SmartSqlWMS仓库管理系统a

pevolo-apiFytSoaCms

喜欢SqlSugar的可以在下面源码点个赞,点个关注

源码: https://github.com/DotNetNext/SqlSugar/