导入数据这种脏活、累活,相信大家多多少少都有经历,常见的场景有:
每种场景有自己的特点,我们一般会根据特点定制做导入数据优化,减少总体导入的耗时,或者避免数据库IO/CPU占用过高,而影响到其他正常业务。
FreeSql 有好几个实用功能,流式读取数据、查询并插入、批量对比更新、插入或修改(支持实体类或字典),用好这些功能可以很方便的实现各种导入数据场景。其实 FreeSql 对应的文档一直都有,只是内容介绍比较零散,这篇文章将针对数据导入详细介绍它们的使用方法,既然 FreeSql bug 少那就多优化一下文档吧!
本文讲解以上四种常见的数据导入实现,让使用者高效解决工作问题。如果你在使用其他更好的导入方案,欢迎加入讨论!
.NET ORM Object Relational Mapping 是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。FreeSql .NET ORM 支持 .NetFramework4.0+、.NetCore、Xamarin、MAUI、Blazor、以及还有说不出来的运行平台,因为代码绿色无依赖,支持新平台非常简单。目前单元测试数量:8500+,Nuget下载数量:1M+。使用最宽松的开源协议 MIT https://github.com/dotnetcore/FreeSql ,可以商用,文档齐全,甚至拿去卖钱也可以。
FreeSql 主要优势在于易用性上,基本是开箱即用,在不同数据库之间切换兼容性比较好,整体的功能特性如下:
8000+个单元测试作为基调,支持10多数数据库,我们提供了通用Odbc理论上支持所有数据库,目前已知有群友使用 FreeSql 操作华为高斯、mycat、tidb 等数据库。安装时只需要选择对应的数据库实现包:
dotnet add packages FreeSql.Provider.Sqlite
static IFreeSql fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=db1.db")
.UseAutoSyncStructure(true) //自动同步实体结构到数据库
.UseNoneCommandParameter(true) //SQL不使用参数化,以便调试
.UseMonitorCommand(cmd => Console.WriteLine(cmd.CommandText)) //打印 SQL
.Build();
FreeSql 提供多种 CRUD 使用习惯,请根据实际情况选择团队合适的一种:
导入数据,正常需要根据源数据量的大小来评估,评估过程需要在实践中慢慢积累,以便选择对应的导入方案。同服务器导入数据的方案有:
1、insert into A(field1, field2) select name, code from B where …
fsql.Select<B>()
.Where(b => b.Time > DateTime.Parse("2022-08-01"))
.InsertInto("A", b => new {
b.Name, b.Code });
如果数据源是多个表组成,也可以:
fsql.Select<B, C>()
.InnerJoin((b, c) => b.Id == c.Id)
.Where((b, c) => b.Time > DateTime.Parse("2022-08-01"))
.InsertInto("A", (b, c) => new {
b.Name, c.Code });
2、分段插入
FreeSql 提供流式分段返回数据,防止读取的数据源量过多时占用内存,假设数据表有100W万记录,我们可以设置每次只返回 1000 条。提示:ToChunk 只执行了一次 SQL 查询。
fsql.Select<B>()
.Where(b => b.Time > DateTime.Parse("2022-08-01"))
.ToChunk(b => new A {
field1 = b.Name, field2 = b.Code }, 1000, cb => {
fsql.Insert(cb