C# 动态创建类,动态创建表,支持多库的数据库维护方案
ccwgpt 2024-12-12 11:06 26 浏览 0 评论
简介
本文主要介绍使用 利用 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,
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
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(){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
相关推荐
- 自己动手写Android数据库框架_android开发数据库搭建
-
http://blog.csdn.net/feiduclear_up/article/details/50557590推荐理由关于Android数据库操作,由于每次都要自己写数据库操作,每次还得去...
- 谷歌开源大模型评测工具LMEval,打通谷歌、OpenAI、Anthropic
-
智东西编译|金碧辉编辑|程茜智东西5月28日消息,据科技媒体TheDecoder5月26日报道,当天,谷歌正式发布开源大模型评测框架LMEval,支持对GPT-4o、Claude3.7...
- 工信部:着力推动大模型算法、框架等基础性原创性的技术突破
-
工信部新闻发言人今日在发布会上表示,下一步,我们将坚持突出重点领域,大力推动制造业数字化转型,推动人工智能创新应用。主要从以下四个方面着力。一是夯实人工智能技术底座。通过科技创新重大项目,着力推动大模...
- 乒乓反复纠结“框架不稳定”的三个小误区
-
很多球友由于对框架的认知不清晰,往往会把“框架不稳定”当成一种心理负担,从而影响学球进度,其典型状态就是训练中有模有样,一旦进入实战,就像被捆住了手脚。通过训练和学习,结合“基本功打卡群”球友们交流发...
- 前AMD、英特尔显卡架构师Raja再战GPU,号称要全面重构堆栈
-
IT之家8月5日消息,知名GPU架构师拉贾科杜里(RajaKoduri)此前曾先后在AMD和英特尔的显卡部门担任要职。而在今日,由Raja创立的GPU软件与IP初创企...
- 三种必须掌握的嵌入式开发程序架构
-
前言在嵌入式软件开发,包括单片机开发中,软件架构对于开发人员是一个必须认真考虑的问题。软件架构对于系统整体的稳定性和可靠性是非常重要的,一个合适的软件架构不仅结构清晰,并且便于开发。我相...
- 怪不得别人3秒就知道软考案例怎么做能50+
-
软考高级统一合格标准必须三科都达到45分,案例分析也一直是考生头疼的一门,但是掌握到得分点,案例能不能50+还不是你们说了算吗?今天就结合架构案例考点,分享实用的备考攻略~一、吃透考点,搭建知识框架从...
- UML统一建模常用图有哪些,各自的作用是什么?一篇文章彻底讲透
-
10万+爆款解析:9大UML图实战案例,小白也能秒懂!为什么需要UML?UML(统一建模语言)是软件开发的“蓝图”,用图形化语言描述系统结构、行为和交互,让复杂需求一目了然。它能:降低沟通成本避...
- 勒索软件转向云原生架构,直指备份基础设施
-
勒索软件组织和其他网络犯罪分子正越来越多地将目标对准基于云的备份系统,对久已确立的灾难恢复方法构成了挑战。谷歌安全研究人员在一份关于云安全威胁演变的报告中警告称,随着攻击者不断改进数据窃取、身份泄露和...
- ConceptDraw DIAGRAM:释放创意,绘就高效办公新未来
-
在当今数字化时代,可视化工具已成为提升工作效率和激发创意的关键。ConceptDrawDIAGRAM,作为一款世界顶级的商业绘图软件,凭借其强大的功能和用户友好的界面,正逐渐成为众多专业人士的首选绘...
- APP 制作界面设计教程:一步到位_app界面设计模板一套
-
想让APP界面设计高效落地,无需繁琐流程,掌握“框架搭建—细节填充—体验优化”三步法,即可一步到位完成专业级设计。黄金框架搭建是基础。采用“三三制布局”:将屏幕横向三等分,纵向保留三...
- MCP 的工作原理:关键组件_mcp部件
-
以下是MCP架构的关键组件:MCP主机:像ClaudeDesktop、GitHubCopilot或旅行助手这样的AI智能体,它们希望通过MCP协议访问工具、资源等。MCP主机会...
- 软件架构_软件架构师工资一般多少
-
软件架构师自身需要是程序员,并且必须一直坚持做一线程序员。软件架构应该是能力最强的一群程序员,他们通常会在自身承接编程任务的同时,逐渐引导整个团队向一个能够最大化生产力的系统设计方向前进。软件系统的架...
- 不知不觉将手机字体调大!老花眼是因为“老了吗”?
-
现在不管是联系、交友,还是购物,都离不开手机。中老年人使用手机的时间也在逐渐加长,刷抖音、看短视频、发朋友圈……看手机的同时,人们也不得不面对“视力危机”——老花眼,习惯眯眼看、凑近看、瞪眼看,不少人...
- 8000通用汉字学习系列讲座(第046讲)
-
[表声母字]加(续)[从声汉字]伽茄泇迦枷痂袈笳嘉驾架咖贺瘸(计14字)嘉[正音]标准音读jiā。[辨形]上下结构,十四画。会意形声字,从壴从加,加也表声。注:从壴,字义与鼓乐有关;从加,字义与...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- mfc框架 (52)
- abb框架断路器 (48)
- beego框架 (52)
- java框架spring (58)
- grpc框架 (65)
- tornado框架 (48)
- 前端框架bootstrap (54)
- orm框架有哪些 (51)
- 知识框架图 (52)
- ppt框架 (55)
- 框架图模板 (59)
- 内联框架 (52)
- cad怎么画框架 (58)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)