C# 動態建立類,動態建立表,支援多庫的資料庫維護方案

2023-03-21 18:01:27

 

 

1、建立表

SqlSugar支援了3種模式的建表(無實體建表、實體建表,實體特性建表),非常的靈活

可以多個資料庫 MYSQL MSSQL ORACLE SQLITE PGSQL 等用同一語法建立資料庫,不需要考慮資料庫的相容性

中間標準:

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=new ConnMoreSettings() {

           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

IsIgnore ORM不處理該列
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(){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(); 

插入

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.NET

WaterCloud微服務

ViperFamilyBucket應用框架通用後臺

SmartSqlWMS倉庫管理系統a

pevolo-apiFytSoaCms 

開源專案地址:https://www.donet5.com/Home/Doc?typeId=1215

 

喜歡SqlSugar的可以在下面原始碼點個贊,點個關注

SqlSugar原始碼: https://github.com/DotNetNext/SqlSugar/