簡介
本文主要介紹使用 利用 SqlSugar 來實現多數據庫的維護 ,動態建類CRUD,動態建表 ,全局過濾器 ,跨庫查詢等功能
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 ,
} |
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菜單等 , 針對不同數據庫都有專門的介紹
6、動態建類,CRUD
如果用DataTable和字典去操作數據庫,那麼在多庫兼容上是不夠用的,很多實體功能不能用,比如過濾器和AOP等等
SqlSugar支持了 動態建類,來實現CRUD
//動態建類可以繼承接口有重載 var type = db.DynamicBuilder().CreateClass("table1", new SugarTable() { }) .CreateProperty("Id", typeof(int),new SugarColumn() { IsPrimaryKey = true, IsIdentity = true }) .CreateProperty("Name",typeof(string), new SugarColumn() { }) .WithCache()//緩存起來根據表名和字段名組合的KEY .BuilderType(); db.CodeFirst.InitTables(type); var value= db.DynamicBuilder().CreateObjectByType(type,new Dictionary<string, object>() { { "Id", 1 }, { "Name", "jack" } }); db.InsertableByObject(value).ExecuteCommand(); db.UpdateableByObject(value).ExecuteCommand(); db.DeleteableByObject(value).ExecuteCommand(); db.StorageableByObject(value).ExecuteCommand();//插入或者更新 db.Queryable<object>().AsType(type).Filter(type).ToList();
總結
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/