C#.NET ORM 如何访问 Access 数据库 [FreeSql]
最近很多 .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();
}
// 或者
```csharp
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/FreeIM | MIT |
FreeRedis | Redis SDK | https://github.com/2881099/FreeRedis | MIT |
csredis | https://github.com/2881099/csredis | MIT | |
FightLandlord | 斗DI主网络版 | https://github.com/2881099/FightLandlord | 学习用途 |
FreeScheduler | 定时任务 | https://github.com/2881099/FreeScheduler | MIT |
IdleBus | 空闲容器 | https://github.com/2881099/IdleBus | MIT |
FreeSql | ORM | https://github.com/dotnetcore/FreeSql | MIT |
FreeSql.Cloud | 分布式tcc/saga | https://github.com/2881099/FreeSql.Cloud | MIT |
FreeSql.AdminLTE | 低代码后台生成 | https://github.com/2881099/FreeSql.AdminLTE | MIT |
FreeSql.DynamicProxy | 动态代理 | https://github.com/2881099/FreeSql.DynamicProxy | 学习用途 |
需要的请拿走,这些都是最近几年的开源作品,以前更早写的就不发了。
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 版本。因此这些项目很难使用到现有的开源库,不能使用可靠的开源库,那么很多时候都要自行实现,在堆积代码的同时,项目也有可能越来越乱,代码越来越渣,项目逐渐变得不稳定。
C#.NET ORM 如何访问 Access 数据库 [FreeSql]的更多相关文章
- ADO访问Access数据库错误解决心得随笔
最近在用ADO访问Access数据库的时候出现了一个奇怪的错误,觉得有必要记录下来,和大家分享一下. 环境 win7 x86系统: VS2012编译器: Office2010: Access2000~ ...
- [转载]Unity3D 访问Access数据库
在开始这个小教程之前呢,其实在网上你已经可以找到相关的资料了,但是我还是要把我自己做练习的一点东西分享出来.写这个教程的主要原因呢,是一个朋友在u3d的官网论坛里,找到了这个demo,但是在他使用的过 ...
- Unity访问Access数据库
首先,准备工作: 创建一个Access 数据库,命名AccessTest.accdb,添加一些数据用于测试 准备System.Data.dll与System.EnterpriseServices.dl ...
- 如何使用.net访问Access数据库 (转)
前言:今天整理程序,看到之前写的一个Demo,也不知道是从哪里参考的了,写到这里,留作备用吧. 使用.net访问Access数据库:1.BL层:新增一个DataAccess类. Code].Defau ...
- Excel中使用VBA访问Access数据库
VBA访问Access数据库 1. 通用自动化语言VBA VBA(Visual Basic For Application)是一种通用自动化语言,它可以使Excel中的常用操作自动化,还可以创建自定义 ...
- vc访问ACCESS数据库
在现代软件开发中,数据库技术被越来越广泛应用,很多项目都存在着大量的数据需要存储,通常都会采用数据库来存储这些数据.最初,数据库厂商推出一个新的数据库产品时,相应的,他会为程序员提供一套访问该数据库的 ...
- Jackcess 1.2.13 发布,Java 访问 Access 数据库
Jackcess 1.2.13 包含新的方法用于在数据库和附件内容解码中查找复杂值类型的关系,修复了 CodeHandler 相关的一些小 bug. Jackcess 是一个Java 类库,用来读写微 ...
- 访问Access数据库(有多个数据库时 体现多态)
如果想编写单机版MIS.小型网站等对数据库性能要求不高的系统,又不想安装SQLServer,可以使用Access(MDAC),只要一个mdb文件就可以了.使用Access创建mdb文件,建表.OleD ...
- golang ODBC 访问access数据库(问题解决之心理路程)
最近项目需要,需要操作access,以前是用VC++ OLE访问,网络用ACE库,感觉很庞大...决定用go试试 网上用的最多的就是这个https://github.com/weigj/go-odbc ...
随机推荐
- 15分钟搭建RocketMQ源码调试环境
下载源码 下载源码,github页面选择(rocketmq-all-4.7.1)版本压缩包,https://github.com/apache/rocketmq/tags 导入IDEA 1. 使用ID ...
- js屏蔽浏览器默认事件
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Axure RP 8 实现 圆角文本框 圆角带筛选的下拉列表框 可自动显示滚动条
刚开始用Axure 会发现 Axure 元件库并不是很齐全,很多元件需要自己想办法解决 或者去网上去找.其实个人建议网上有现成的元件可以就下载就不必花时间去折腾.除非你也想练练手,原型这种东西除非高保 ...
- Java学习 (五)基础篇 数据类型
目录 数据类型 强类型语言 弱类型语言 Java数据类型分为两大类 八大字节类型(重点) Java数据类型拓展 整数拓展:进制 浮点数拓展 字符类型 布尔值拓展 数据类型 强类型语言 要求变量的使用要 ...
- 【原创】Selenium获取请求头、响应头
本文仅供学习交流使用,如侵立删! Selenium获取请求头.响应头 操作环境 win10 . mac Python3.9 selenium.seleniumwire selenium是没有办法直接获 ...
- 技术分享 | MySQL数据误删除的总结
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 内容提要 用delete语句 使用drop.truncate删除表以及drop删 ...
- 让Python更优雅更易读(第一集)
变量和注释 1.变量 在编写变量尽量要让其清晰只给,让人清除搞清楚代码的意图 下方两段代码作用完全一样,但第二段代码是不是更容易让人理解 value = s.strip() username = in ...
- Luogu2420 让我们异或吧 (熟练剖分)
\(dis[u] \bigoplus dis[v] = dis[u] \bigoplus dis[v] \bigoplus dis[lca\{x,y\}] \bigoplus dis[lca\{x,y ...
- 小技巧---eclipse 全选lib jar包
按住shift键,点击第一个jar包,然后点击最后一个jar包,就全选了所有jar包,然后添加build path 添加到类路径
- 7个技巧让你写出干净的 TSX 代码
原文链接:https://dev.to/ruppysuppy/7-tips-for-clean-react-typescript-code-you-must-know-2da2 "干净的代码 ...