• FreeSql 导入数据的各种场景总结 [C#.NET ORM]


    💻 前言

    导入数据这种脏活、累活,相信大家多多少少都有经历,常见的场景有:

    • 同服务器从A表导数据到B表
    • 批量导入新数据
    • 批量新增或更新数据
    • 跨服务器从A表导数据到B表

    每种场景有自己的特点,我们一般会根据特点定制做导入数据优化,减少总体导入的耗时,或者避免数据库IO/CPU占用过高,而影响到其他正常业务。

    FreeSql 有好几个实用功能,流式读取数据、查询并插入、批量对比更新、插入或修改(支持实体类或字典),用好这些功能可以很方便的实现各种导入数据场景。其实 FreeSql 对应的文档一直都有,只是内容介绍比较零散,这篇文章将针对数据导入详细介绍它们的使用方法,既然 FreeSql bug 少那就多优化一下文档吧!

    本文讲解以上四种常见的数据导入实现,让使用者高效解决工作问题。如果你在使用其他更好的导入方案,欢迎加入讨论!


    🌳 C#.NET ORM概念

    .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.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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    FreeSql 提供多种 CRUD 使用习惯,请根据实际情况选择团队合适的一种:

    • 要么 FreeSql,原始用法;
    • 要么 FreeSql.Repository,仓储+工作单元习惯;
    • 要么 FreeSql.DbContext,很像 EFCore 的使用习惯;
    • 要么 FreeSql.BaseEntity,充血模式;
    • 要么 直接像 dapper 那样使用 DbConnection 扩展方法;

    ⚡ 场景一:同服务器从A表导数据到B表

    导入数据,正常需要根据源数据量的大小来评估,评估过程需要在实践中慢慢积累,以便选择对应的导入方案。同服务器导入数据的方案有:


    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 });
    
    • 1
    • 2
    • 3
    • 4

    如果数据源是多个表组成,也可以:

    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 });
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    比较Hive数据库与MySQL数据库
    (min,max)=>Math.floor(Math.random()*(max-min+1)+min
    矩阵与拉普拉斯展开定理求解多元一次方程组
    获取拼多多商品信息操作详情
    【无标题】
    MySQL高级篇知识点——索引的数据结构
    【Qt 学习笔记】Qt常用控件 | 输入类控件 | Combo Box的使用及说明
    正则表达式replaceAll()方法具有什么功能呢?
    Linux课程四课---Linux开发环境的使用(gcc/g++编译器的相关)
    音频编解码,利用FAAC来实现AAC编码
  • 原文地址:https://blog.csdn.net/dotnetCore/article/details/126752797