最近很多 .net QQ 群无端被封停,特地是 wpf 群简直全军覆没。依乐祝的 .net6 交换群,晓晨的 .net 跨平台交换群,导致很多码友颠沛流离无家可归,借此机会应用一次召唤术,有须要的请加群:560611514【.NET C# 爱好者】,6406277【C#/.Net Core 社区】,822074314【DotNet 开发交换群】
💻 前言
看到题目点进来,兴许有人问,为什么不必 mysql,为什么不必 sqlite,为什么不这样那样。
其实有时候情非得已,被迫应用不由得本人抉择,没有谁天天做新我的项目,新我的项目当然不会选 Access 数据库,简单的业务群体对方发送过去的文件是 Access 也没得选,难道能够要求对方公司换数据库?
Microsoft Office Access 是由微软公布的关系数据库管理系统。它联合了 MicrosoftJet Database Engine 和 图形用户界面两项特点,是 Microsoft Office 的零碎程序之一。
Microsoft Office Access 是微软把数据库引擎的图形用户界面和软件开发工具联合在一起的一个数据库管理系统。它是微软 OFFICE 的一个成员, 在包含专业版和更高版本的 office 版本外面被独自发售。2018 年 9 月 25 日, 最新的微软 Office Access 2019 在微软 Office 2019 里公布。
MS ACCESS 以它本人的格局将数据存储在基于 Access Jet 的数据库引擎里。它还能够间接导入或者链接数据(这些数据存储在其余应用程序和数据库)。
🌳 C#.NET 拜访 Access 数据库
从 .NETframework 1.0 到现今的 dotnet-7.0,拜访 Access 数据库都只能用 oledb 形式,微软历史拜访数据库的形式有许多种(ado、odbc、oledb、ado.net),oledb 是其中的一种。
连贯字符串常见的有两种:
- Provider=Microsoft.Jet.OleDb.4.0;Data Source=d:/accdb/2003.mdb
- Provider=Microsoft.ACE.OLEDB.12.0;Data Source=d:/accdb/2007.accdb
Access 反对 SQL 语句,应用起来和一般关系型数据库差不多,因为不想在代码中写 SQL,为了让 crud 操作起来更加便当,决定引入 C#.NET ORM Freesql,因为他反对 .NETFramework 4.0 及当前的所有 dotnet 版本,适应范畴更广。
🦄 FreeSql 介绍
.NET ORM Object Relational Mapping 是一种为了解决面向对象与关系数据库存在的互不匹配的景象的技术。
FreeSql .NET ORM 反对 .NetFramework4.0+、.NetCore、Xamarin、MAUI、Blazor、以及还有说不出来的运行平台,因为代码 绿色无依赖,反对新平台非常简单。目前单元测试数量:8500+,Nuget 下载数量:1M+。应用最宽松的开源协定 MIT https://github.com/dotnetcore/FreeSql,能够商用,文档齐全,甚至拿去卖钱也能够。
FreeSql 次要劣势在于易用性上,根本是开箱即用,在不同数据库之间切换兼容性比拟好,整体的性能个性如下:
- 反对 CodeFirst 比照构造变动迁徙、DbFirst 从数据库生成实体类;
- 反对 丰盛的表达式函数,独特的自定义解析;
- 反对 批量增加、批量更新、BulkCopy、导航属性,贪心加载、延时加载、级联保留、级联删除;
- 反对 读写拆散、分表分库,租户设计,分布式事务;
- 反对 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/ 达梦 / 神通 / 人大金仓 / 翰高 /Clickhouse/MsAccess Ado.net 实现包,以及 Odbc 的专门实现包;
8000+ 个单元测试作为基调,反对 10 少数数据库,咱们提供了通用 Odbc 实践上反对所有数据库,目前已知有群友应用 FreeSql 操作华为高斯、mycat、tidb 等数据库。装置时只须要抉择对应的数据库实现包:
dotnet add packages FreeSql.Provider.MsAccess
public class DB
{static Lazy<IFreeSql> accessLazy = new Lazy<IFreeSql>(() => new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.MsAccess, "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=d:/accdb/2007.accdb")
//.UseAutoSyncStructure(true) 主动建表,适宜新我的项目
.UseNoneCommandParameter(true)
.UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText))
.Build());
public static IFreeSql access => accessLazy.Value;
}
定义 DB.cs 类之后就能够高兴的 CRUD 了。FreeSql 提供多种 CRUD 应用习惯,请依据理论状况抉择团队适合的一种:
- 要么 FreeSql,原始用法;
- 要么 FreeSql.Repository,仓储 + 工作单元习惯;
- 要么 FreeSql.DbContext,很像 EFCore 的应用习惯,兼容 EFCore 99% 的实体注解;
- 要么 FreeSql.BaseEntity,充血模式;
- 要么 间接像 dapper 那样应用 SqlConnection 扩大办法;
⚡ CRUD 模式一:原始用法 API
DB.access.Select<T>(); // 查问
DB.access.Insert<T>(); // 插入
DB.access.Update<T>(); // 更新
DB.access.Delete<T>(); // 删除
DB.access.InsertOrUpdate<T>()// 插入或更新
DB.access.Transaction(..); // 事务
DB.access.CodeFirst; //CodeFirst 对象
DB.access.DbFirst; //DbFirst 对象
DB.access.Ado; //Ado 对象
DB.access.Aop; //Aop 对象
DB.access.GlobalFilter; // 全局过滤器对象
var blogs = DB.access.Select<Blog>()
.Where(b => b.Rating > 3)
.OrderBy(b => b.Url)
.Page(2, 10)
.ToList();
var blog = new Blog {Url = "http://sample.com"};
blog.BlogId = (int)DB.access.Insert(blog).ExecuteIdentity();
DB.access.Update<Blog>()
.Set(b => b.Url, "http://sample2222.com")
.Where(b => b.Url == "http://sample.com")
.ExecuteAffrows();
DB.access.Delete<Blog>()
.Where(b => b.Url == "http://sample.com")
.ExecuteAffrows();
// 等等等。。级联保留、级联查问、导航属性。。。
⛳ CRUD 模式二:仓储 + 工作单元
FreeSql.Repository 作为扩大,实现了通用仓储层性能。与其余标准规范一样,仓储层也有相应的标准定义。FreeSql.Repository 参考 abp vnext 接口,定义和实现根底的仓储层(CURD),算比拟通用的办法。
- Select/Attach 快照对象,Update 只更新变动的字段;
- Insert 插入数据,适配各数据库优化执行 ExecuteAffrows/ExecuteIdentity/ExecuteInserted;
- InsertOrUpdate 插入或更新;
- SaveMany 办法疾速保留导航对象(一对多、多对多);
- 工作单元治理事务
//Startup.cs
public void ConfigureServices(IServiceCollection services)
{services.AddSingleton<IFreeSql>(DB.access);
services.AddScoped<UnitOfWorkManager>();
services.AddFreeRepository(null, typeof(Startup).Assembly);
// 批量注入 Service
}
public class SongService
{
readonly IBaseRepository<Song> _repoSong;
readonly IBaseRepository<Detail> _repoDetail;
public SongService(IBaseRepository<Song> repoSong, IBaseRepository<Detail> repoDetail)
{
_repoSong = repoSong;
_repoDetail = repoDetail;
}
[Transactional]
public virtual void Test1()
{
// 这里 _repoSong、_repoDetail 所有操作都是一个工作单元
this.Test2();}
[Transactional(Propagation = Propagation.Nested)]
public virtual void Test2() // 嵌套事务
{// 这里 _repoSong、_repoDetail 所有操作都是一个工作单元}
}
属性 | 返回值 | 阐明 |
---|---|---|
EntityType | Type | 仓储正在操作的实体类型,留神它不肯定是 TEntity |
UnitOfWork | IUnitOfWork | 正在应用的工作单元 |
Orm | IFreeSql | 正在应用的 Orm |
DbContextOptions | DbContextOptions | 正在应用的 DbContext 设置,批改设置不影响其余 |
DataFilter | IDataFilter\<TEntity\> | 仓储过滤器,本对象内失效 |
UpdateDiy | IUpdate\<TEntity\> | 筹备更新数据,与仓储同事务 |
Select | ISelect\<TEntity\> | 筹备查问数据 |
办法 | 返回值 | 参数 | 阐明 |
---|---|---|---|
AsType | void | Type | 扭转仓储正在操作的实体类型 |
Get | TEntity | TKey | 依据主键,查问数据 |
Find | TEntity | TKey | 依据主键,查问数据 |
Delete | int | TKey | 依据主键删除数据 |
Delete | int | Lambda | 依据 lambda 条件删除数据 |
Delete | int | TEntity | 删除数据 |
Delete | int | IEnumerable\<TEntity\> | 批量删除数据 |
DeleteCascadeByDatabase | List\<object\> | Lambda | 依据导航属性递归数据库删除数据 |
Insert | – | TEntity | 插入数据,若实体有自增列,插入后的自增值会填充到实体中 |
Insert | – | IEnumerable\<TEntity\> | 批量插入数据 |
Update | – | TEntity | 更新数据 |
Update | – | IEnumerable\<TEntity\> | 批量更新数据 |
InsertOrUpdate | – | TEntity | 插入或更新数据 |
FlushState | – | 无 | 革除状态治理数据 |
Attach | – | TEntity | 附加实体到状态治理,可用于不查问就更新或删除 |
Attach | – | IEnumerable\<TEntity\> | 批量附加实体到状态治理 |
AttachOnlyPrimary | – | TEntity | 只附加实体的主键数据到状态治理 |
SaveMany | – | TEntity, string | 保留实体的指定 ManyToMany/OneToMany 导航属性(残缺比照) |
BeginEdit | – | List\<TEntity\> | 筹备编辑一个 List 实体 |
EndEdit | int | 无 | 实现编辑数据,进行保留动作 |
状态治理,可实现 Update 只更新变动的字段(不更新所有字段),灵便应用 Attach 和 Update 用起来十分难受。
⚡ CRUD 模式三:DbContext
FreeSql.DbContext 实现相似 EFCore 应用习惯,跟踪对象状态,最终通过 SaveChanges 办法提交事务。
FreeSql 可自动识别 EFCore 实体个性 Key/Required/NotMapped/MaxLength/StringLength/DatabaseGenerated/Table/Column。
- Select/Attach 快照对象,Update 只更新变动的字段;
- Add/AddRange 插入数据,适配各数据库优化执行 ExecuteAffrows/ExecuteIdentity/ExecuteInserted;
- AddOrUpdate 插入或更新;
- SaveMany 办法疾速保留导航对象(一对多、多对多);
using (var ctx = DB.oracle.CreateDbContext()) {//var db1 = ctx.Set<Song>();
//var db2 = ctx.Set<Tag>();
var item = new Song { };
ctx.Add(item);
ctx.SaveChanges();}
// 或者
public class SongContext : DbContext {public DbSet<Song> Songs { get; set;}
public DbSet<Tag> Tags {get; set;}
protected override void OnConfiguring(DbContextOptionsBuilder builder) {builder.UseFreeSql(DB.oracle);
}
// 每个 DbContext 只触发一次
protected override void OnModelCreating(ICodeFirst codefirst)
{
codefirst.Entity<Song>(eb =>
{eb.ToTable("tb_song");
eb.Ignore(a => a.Field1);
eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired();
eb.Property(a => a.Url).HasMaxLength(100);
}
}
}
提醒:FreeSql 兼容 EFCore 99% 的实体个性
🌴 CRUD 模式四:BaseEntity
BaseEntity 是一种极简略的 CodeFirst 开发方式,特地对单表或多表 CRUD,利用继承节俭了每个实体类的反复属性(创立工夫、ID 等字段),软件删除等性能,进行 crud 操作时不用时常思考仓储的应用;
dotnet add package FreeSql.Extensions.BaseEntity
public class UserGroup : BaseEntity<UserGroup, int>
{public string GroupName { get; set;}
}
// 增加
var item = new UserGroup {GroupName = "组一"};
item.Insert();
// 更新
item.GroupName = "组二";
item.Update();
// 增加或更新
item.Save();
// 软删除
item.Delete();
// 复原软删除
item.Restore();
// 依据主键获取对象
var item = UserGroup.Find(1);
// 查问数据
var items = UserGroup.Where(a => a.Id > 10).ToList();
📃 CRUD 模式五:SqlConnection 扩大办法(相似 Dapper)
提供了相似 Dapper 的应用办法,FreeSql 减少了 IDbConnection/IDbTransaction 对象的扩大办法 Select/Insert/Update/Delete 实现 CRUD。
using FreeSql;
using (var conn = new SqlConnection(...))
{conn.Select<T>().Where(...).ToList();
conn.Insert(new T {}).ExecuteAffrows();
conn.Update().SetSource(new T {}).ExecuteAffrows();
conn.InsertOrUpdate().SetSource(new T {}).ExecuteAffrows();
conn.Delete<T>().Where(...).ExecuteAffrows();}
- 每个 SqlConnection GetFreeSql() 返回的 IFreeSql 实例雷同;
- 能够对 fsql 设置 Aop 事件,比方监督 SQL;
- IFreeSql 本身的成员 IDbFirst、Transaction 不可用;
利用本性能能够疾速将 FreeSql 应用到我的项目中,只须要解决好实体类的个性。
🌈 结束语
作者是什么人?
作者是一个入行 18 年的老批,他目前写的.net 开源我的项目有:
开源我的项目 | 形容 | 开源地址 | 开源协定 |
---|---|---|---|
FreeIM | 聊天零碎架构 | https://github.com/2881099/Fr… | MIT |
FreeRedis | Redis SDK | https://github.com/2881099/Fr… | MIT |
csredis | https://github.com/2881099/cs… | MIT | |
FightLandlord | 斗 DI 主网络版 | https://github.com/2881099/Fi… | 学习用处 |
FreeScheduler | 定时工作 | https://github.com/2881099/Fr… | MIT |
IdleBus | 闲暇容器 | https://github.com/2881099/Id… | MIT |
FreeSql | ORM | https://github.com/dotnetcore… | MIT |
FreeSql.Cloud | 分布式 tcc/saga | https://github.com/2881099/Fr… | MIT |
FreeSql.AdminLTE | 低代码后盾生成 | https://github.com/2881099/Fr… | MIT |
FreeSql.DynamicProxy | 动静代理 | https://github.com/2881099/Fr… | 学习用处 |
须要的请拿走,这些都是最近几年的开源作品,以前更早写的就不发了。
FreeSql .NET ORM 反对 .NetFramework4.0+、.NetCore、Xamarin、MAUI、Blazor、以及还有说不出来的运行平台,因为代码 绿色无依赖,反对新平台非常简单。目前单元测试数量:8500+,Nuget 下载数量:1M+。QQ 群:4336577(已满)、8578575(在线)、52508226(在线)
- 反对 CodeFirst 模式;
- 反对 DbFirst 模式,反对从数据库导入实体类,或应用实体类生成工具生成实体类;
- 反对 丰盛的表达式函数,以及灵便的自定义解析;
- 反对 导航属性一对多、多对多贪心加载,延时加载,级联保留,级联删除;
- 反对 读写拆散、分表分库、过滤器、乐观锁、乐观锁、分布式事务、多租户(按字段 / 表 / 库);
- 反对 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/ 达梦 / 人大金仓 / 神舟通用 / 南大通用 / 翰高 / 华为高斯 /ClickHouse/Access 等数据库;
FreeSql 应用最宽松的开源协定 MIT https://github.com/dotnetcore/FreeSql,能够商用,文档齐全,甚至拿去卖钱也能够。
8500+ 个单元测试作为基调,反对 10 少数数据库,咱们提供了通用 Odbc 实践上反对所有数据库,目前已知有群友应用 FreeSql 操作华为高斯、mycat、tidb 等数据库。装置时只须要抉择对应的数据库实现包。
轻量化解释:理解 FreeRedis、FreeSql、csredis 的人都晓得,咱们公布的开源我的项目是绿色著称,零依赖公布后只有一个 DLL,不会造成使用者我的项目依赖抵触,反对 .NET 4.0 堪称屎山我的项目的救星。当初还有很多.NET FX4.0 的我的项目,这些我的项目因历史遗留起因或硬件限度,不能更换 .NET Core 版本。因而这些我的项目很难应用到现有的开源库,不能应用牢靠的开源库,那么很多时候都要自行实现,在沉积代码的同时,我的项目也有可能越来越乱,代码越来越渣,我的项目逐步变得不稳固。