C# 動態(tài)創(chuàng)建類,動態(tài)創(chuàng)建表,支持多庫的數(shù)據(jù)庫維護方案
一、創(chuàng)建表
SqlSugar支持了3種模式的建表(無實體建表、實體建表,實體特性建表),非常的靈活
可以多個數(shù)據(jù)庫 MYSQL MSSQL ORACLE SQLITE PGSQL 等用同一語法創(chuàng)建數(shù)據(jù)庫,不需要考慮數(shù)據(jù)庫的兼容性
中間標準:
| string 大文本 | 5.1.3.44-preview06 推薦[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)] |
|---|---|
| string 設(shè)置長度的字符串 | [SugarColumn(Length=10)] public string FieldName{ get; set; } |
| int 整數(shù) | public int FieldName{ get; set; } |
| short 整數(shù)小 | public short FieldName{ get; set; } |
| long 大數(shù)字 | 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; } |
| 枚舉 (數(shù)據(jù)庫存int) | public 枚舉 FieldName{ get; set; } |
| byte[] 二進制 | public byte[] FileInfo{get;set;}建議:升級到 SqlSugarCore 5.1.3.46-preview09 及以上對多庫支持了比較好 |
| SqlServer特殊配置:和他庫不同一般選用Nvarchar,可以使用這個配置讓他和其他數(shù)據(jù)庫區(qū)分(其他庫是varchar) | DbType = SqlSugar.DbType.SqlServer,`` ``ConnectionString ="字符串",`` ``IsAutoCloseConnection = ``true``,`` ``MoreSettings=``new ConnMoreSettings() {`` `` ``SqlServerCodeFirstNvarchar= ``true``,`` `` ``} |
1.1、通過特性建表
我們可以通過創(chuàng)建實體來進行建表
public class CodeFirstTable1
{
[SugarColumn(IsIdentity = true, IsPrimaryKey = true)]
public int Id { get; set; }
public string Name { get; set; }
//ColumnDataType 自定格式的情況 length不要設(shè)置 (想要多庫兼容看4.2和9)
[SugarColumn(ColumnDataType = "Nvarchar(255)")]
public string Text { get; set; }
[SugarColumn(IsNullable = true)]//可以為NULL
public DateTime CreateTime { get; set; }
}
/***創(chuàng)建單個表***/
db.CodeFirst.SetStringDefaultLength(200).InitTables(typeof(CodeFirstTable1));//這樣一個表就能成功創(chuàng)建了
/***手動建多個表***/
db.CodeFirst.SetStringDefaultLength(200)
.InitTables(typeof(CodeFirstTable1),typeof(CodeFirstTable2));
建表特性如下
| 名稱 | 描述 |
|---|---|
| IsIdentity | 是否創(chuàng)建自增標識 |
| IsPrimaryKey | 是否創(chuàng)建主鍵標識 |
| ColumnName | 創(chuàng)建數(shù)據(jù)庫字段的名稱(默認取實體類屬性名稱) |
| ColumnDataType | 創(chuàng)建數(shù)據(jù)庫字段的類型用法1:“varchar(20)” 不需要設(shè)置長度用法2: 不設(shè)置該參數(shù) 系統(tǒng)會根據(jù)C#類型自動生成相應(yīng)的數(shù)據(jù)庫類型 用法3: 多庫兼容可以用 :看標題9 |
| IsIgnore | ORM不處理該列 |
| ColumnDescription | 備注 表注釋 (新版本支持XML文件) |
| Length | 長度 設(shè)成10會生成 xxx類型(10), 沒括號的不設(shè)置 |
| IsNullable | 是否可以為null默為false |
| DecimalDigits | 精度 如 decimal(18,2) length=18,DecimalDigits=2 |
| OracleSequenceName | 設(shè)置Oracle序列,設(shè)置后該列等同于自增列 |
| OldColumnName | 修改列名用,這樣不會新增或者刪除列 |
| IndexGroupNameList | 已棄用 ,新用法看文檔4.3 |
| UniqueGroupNameList | 已棄用, 新用法看文檔4.3 |
| 注意:有2個屬性用處不同DefaultValue IsOnlyIgnoreInsert | DefaultValue=默認值 用來建表設(shè)置字段默認值IsOnlyIgnoreInsert=true 插入數(shù)據(jù)時取默認值很多情況需要2個一起使用如果只建表不插入數(shù)據(jù)用1個 如果建表并且插入數(shù)據(jù)用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實體進行相關(guān)配置
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實體進行相關(guān)配置
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用法
})
//可以結(jié)合全局邏輯一起使用,下面的和上面的有沖突的話,下面會覆蓋上面的
//統(tǒng)一設(shè)置 nullable等于isnullable=true
//低版本C#看標題2.2
if(p.IsPrimaryKey==false&&new NullabilityInfoContext()
.Create(c).WriteState is NullabilityState.Nullable)
{
p.IsNullable = true;
}
}
}
});
//性能說明:
//EntityService 相同實體只會執(zhí)行一次性不需太操作
1.3、無實體建表
功能與實體建類一模一樣,如果使用SqlSugar中間標準可以支持多個數(shù)據(jù)庫一套代碼建表
var type = db.DynamicBuilder().CreateClass("UnitEntityA",
new SugarTable()
{
TableDescription = "表備注",
//DisabledUpdateAll=true 可以禁止更新只創(chuàng)建
}
)
.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);
三、數(shù)據(jù)庫維護
SqlSugar有一套數(shù)據(jù)庫維護API,并且能夠很好的支持多種數(shù)據(jù)庫,例如備份數(shù)據(jù)庫等常用功能
//例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 | 獲取所有數(shù)據(jù)庫名稱 | List |
|---|---|---|
| GetViewInfoList | 查詢所有視圖 | List |
| GetTableInfoList | 獲取所有表,查詢所有的表 (GetTableInfoList(是否緩存)) | List |
| GetColumnInfosByTableName | 獲取列根據(jù)表名,獲取字段,字段信息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 | 創(chuàng)建索引,唯一約束(唯一索引) | bool |
| IsAnyIndex | 索引是否存在 | bool |
| GetIndexList | 獲取所有索引 | |
| GetProcList | 獲取所有存儲過程 |
可以自動識別在哪個庫
實體
[TenantAttribute("1")]//對應(yīng)ConfigId
public class C1Table
{
public string Id { get; set; }
}
[TenantAttribute("2")]
public class C2Table
{
public string Id { get; set; }
}
查詢
//通過ConfigId進行數(shù)據(jù)庫區(qū)分
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 }
});
//自動跨庫聯(lián)表查詢
var query5 = db.QueryableWithAttr<Order>()//如果MySql和SqlServer自動支持同服務(wù)器的跨庫聯(lián)表查詢
.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();
//手動跨庫聯(lián)表查詢 ,這種方式結(jié)合dblink可以跨服務(wù)器
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()
只要實體配置了數(shù)據(jù)庫,就不要考慮換庫了,直接使用,并且支持事務(wù)
四、過濾器
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();//還原過濾器 (適合下面代碼還需要過濾器情況)
五、子查詢升級
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();
六、自定義類型支持
自定義類型轉(zhuǎn)換器
下面只是講解怎么定義轉(zhuǎn)換器,ORM自帶的功能就包含下面功能,只是用來講解
public class DictionaryConvert : ISugarDataConverter
{
public SugarParameter ParameterConverter<T>(object value, int i)
{
//該功能ORM自帶的IsJson就能實現(xiàn)這里只是用這個用例來給大家學習
var name = "@myp" + i;
var str = new SerializeService().SerializeObject(value);
return new SugarParameter(name, str);
}
public T QueryConverter<T>(IDataRecord dr, int i)
{
//打斷點調(diào)試
//該功能ORM自帶的IsJson就能實現(xiàn)這里只是用這個用例來給大家學習
var str = dr.GetValue(i) + "";
return new SerializeService().DeserializeObject<T>(str);
}
}
//使用自定義轉(zhuǎn)換器
[SugarColumn(ColumnDataType="varchar(2000)",SqlParameterDbType=typeof(DictionaryConvert))]
public Dictionary<string, object> DcValue { get; set; }//5.1.3.53-preview08
現(xiàn)有類型支持
json類型
https://www.donet5.com/Home/Doc?typeId=1232
枚舉類型
int存儲:直接用就行了
public DbType DcValue { get; set; }
string存儲:高版本如下寫法
[SugarColumn(ColumnDataType="varchar(20)",SqlParameterDbType=typeof(EnumToStringConvert))]
public DbType DcValue { get; set; }
3、數(shù)據(jù)庫獨有類型支持
看左邊菜單 【數(shù)據(jù)庫特性】 該菜單下面有 SqlServer菜單或者MySql菜單等,針對不同數(shù)據(jù)庫都有專門的介紹
總結(jié)
SqlSugar在2021年到2022年大量的開源應(yīng)用使用了SqlSugar,帶動了SqlSugar的快速發(fā)展,我這邊要感謝大家
Admin.NET通用管理平臺
ZrAdminNetCore 后臺
管理Yi框架(Ruoyi Vue)
SimpleAdmin (new)
vboot-netmagic.net (Vue2.0)
網(wǎng)關(guān)采集系統(tǒng)(Blazor)
RuYiAdmin
CoreShop商城
Blog.Core
YuebonCore
企業(yè)級框架Furion
WebFirst
騰訊APIJSON.NET
WaterCloud微服務(wù)
ViperFamilyBucket應(yīng)用框架通用后臺
SmartSqlWMS倉庫管理系統(tǒng)a
pevolo-apiFytSoaCms
開源項目
https://www.donet5.com/Home/Doc?typeId=1215
轉(zhuǎn)自:果糖大數(shù)據(jù)科技
鏈接:cnblogs.com/sunkaixuan/p/17240546.html

