当前位置: 首页 > article >正文

EFCore postgresql 批量删除、插入、更新

我用的.net 6

  1. 安装依赖包
> Microsoft.EntityFrameworkCore              6.0.33    6.0.33 
> Microsoft.EntityFrameworkCore.Tools        6.0.33    6.0.33 
> Npgsql.EntityFrameworkCore.PostgreSQL      6.0.29    6.0.29 
> Z.EntityFramework.Extensions.EFCore        6.103.4   6.103.4
  1. 添加配置
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "DataBaseConfig": {
    "Host": "192.168.214.133",
    "Port": 32222,
    "UserName": "postgresadmin",
    "Password": "admin123",
    "DataBase": "postgresdb"
  }
}

  1. 添加实体类,实体配置,以及配置类
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace EFCoreBulkInsert
{
    public class Config
    {
        public int Port { get; set; }

        public string Host { get; set; }

        public string UserName { get; set; }

        public string Password { get; set; }

        public string DataBase { get; set; }
    }


    public class Test
    {
        public int ID { get; set; }

        public string Name { get; set; }
    }

    public class TestConfig : IEntityTypeConfiguration<Test>
    {
        public void Configure(EntityTypeBuilder<Test> builder)
        {
            builder.ToTable("test");
            builder.HasKey(t => t.ID);
            builder.Property(t => t.ID).HasColumnName("id");
            builder.Property(t => t.Name).HasColumnName("name");
        }
    }
}

  1. 添加dbcontext
using Microsoft.EntityFrameworkCore;

namespace EFCoreBulkInsert
{
    public class CustomDBContext : DbContext
    {
        public DbSet<Test> bulkTestConfigs { get; set; }
        public CustomDBContext(DbContextOptions<CustomDBContext> options) : base(options)
        {

        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
        }
    }
}

  1. DI
builder.Services.Configure<Config>(builder.Configuration.GetSection("DataBaseConfig"));

builder.Services.AddScoped<Config>();

builder.Services.AddDbContext<CustomDBContext>((sp,options) =>
{
    var config = sp.GetRequiredService<IOptionsSnapshot<Config>>();
    options.UseNpgsql($"Host={config.Value.Host};Port={config.Value.Port};Database={config.Value.DataBase};Username={config.Value.UserName};Password={config.Value.Password}")
    .LogTo(Console.WriteLine, new[] { DbLoggerCategory.Database.Command.Name }, LogLevel.Information)
                   .EnableSensitiveDataLogging();
});

  1. controller
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;

namespace EFCoreBulkInsert.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class BulkController : ControllerBase
    {
        public readonly CustomDBContext _customDBContext;

        public BulkController(CustomDBContext customDBContext)
        {
            _customDBContext = customDBContext;
        }

        [HttpPost]
        public async Task<IActionResult> BulkInsert([FromBody] int count)
        {
            Stopwatch  stopwatch = Stopwatch.StartNew();
            stopwatch.Start();
            List<Test> tests = new List<Test>();

            for (int i = 0; i < count; i++)
            {
                tests.Add(new Test { Name = i.ToString() });
            }

            _customDBContext.BulkInsert(tests, options => {
                options.AutoMapOutputDirection = false;
                options.InsertIfNotExists = true;
                options.BatchSize = 100;
            });
            stopwatch.Stop();

            return Ok(new { time= stopwatch.Elapsed });
        }


        [HttpPost]
        public async Task<IActionResult> BulkUpdate([FromBody] List<int> ids)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            stopwatch.Start();
            List<Test> tests = new List<Test>();

            foreach (var item in ids)
            {
                tests.Add(new Test() { ID = item, Name = "haha" + item.ToString() });
            }

            //以下两种写法都行
            await _customDBContext.BulkUpdateAsync(tests, options =>
            {
                options.ColumnInputExpression = x => new { x.Name };
            });


            await _customDBContext.BulkUpdateAsync(tests, options =>
            {
                options.ColumnInputNames = new List<string> { "Name" };
            });

            stopwatch.Stop();

            return Ok(new { time = stopwatch.Elapsed });
        }


        [HttpPost]
        public async Task<IActionResult> BulkDelete([FromBody] List<int> ids)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            stopwatch.Start();


            await _customDBContext.BulkDeleteAsync(_customDBContext.bulkTestConfigs.Where(x => ids.Contains(x.ID)));
            stopwatch.Stop();

            return Ok(new { time = stopwatch.Elapsed });
        }


        [HttpPost]
        public async Task<IActionResult> BulkMergeUpdate([FromBody] Dictionary<string,string> keyValuePairs)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            stopwatch.Start();

            List<Test> tests = new List<Test>();
            foreach (var item in keyValuePairs)
            {
                tests.Add(new Test { ID = Convert.ToInt16(item.Key), Name = item.Value });
            }

            await _customDBContext.BulkMergeAsync(tests, options =>
            {
                options.ColumnPrimaryKeyNames = new List<string> { "ID" }; //通过指定ID参数,达到更新的效果
                //options.IgnoreOnMergeInsertNames = new List<string>() { "UpdatedDate", "UpdatedBy" }; //插入忽略的属性

                //options.IgnoreOnMergeUpdateExpression = x => new { x.CreatedDate, x.CreatedBy }; // 更新忽略的属性

            });
            stopwatch.Stop();

            return Ok(new { time = stopwatch.Elapsed });
        }
    }
}

Bulk Insert

以下是一些常用的参数设置

  • AutoMapOutputDirection: This option allows to optimize performance by not returning outputting values such as identity values.
  • InsertIfNotExists: This option ensures only new entities that don’t already exist in the database are inserted.
  • InsertKeepIdentity: This option allows insertion of specific values into an identity column from your entities.
  • IncludeGraph: This option enables insertion of entities along with all related entities found in the entity graph, maintaining the relationships.

Bulk Update

  • ColumnPrimaryKeyExpression: This option allows you to use a custom key to check for pre-existing entities.
  • ColumnInputExpression: This option enables you to specify a subset of columns to update by using an expression.
  • ColumnInputNames: This option allows you to specify a subset of columns to update by providing their names.
  • IncludeGraph: This option allow updating entities along with all related entities found in the entity graph, maintaining the data relationships.

Bulk Delete

  • ColumnPrimaryKeyExpression: This option allows the usage of a custom key to verify the existence of entities.
  • DeleteMatchedAndConditionExpression: This option enables you to perform or skip the deletion action based on whether all values from the source and destination are equal for the specified properties.
  • DeleteMatchedAndOneNotConditionExpression: This option allows you to perform or skip the deletion action if at least one value from the source differs from the destination for the specified properties.
  • DeleteMatchedAndFormula: This option lets you perform or skip the deletion action based on a predefined SQL condition.

官网

源码


http://www.kler.cn/news/335456.html

相关文章:

  • Java - Spring框架 (ios+aop)
  • c基础面试题
  • 如何创建一个docker,给它命名,且下次重新打开它
  • 数据结构——List接口
  • SpringBoot中的数据库查询及Mybatis和MybatisPlus的使用
  • Windows环境 源码编译 FFmpeg
  • 828华为云征文|部署开源超轻量中文OCR项目 TrWebOCR
  • JavaWeb的小结02
  • 【无人水面艇路径跟随控制2】(C++)USV代码阅读: SetOfLos 类的从路径点和里程计信息中计算期望航向
  • 数据结构:将复杂的现实问题简化为计算机可以理解和处理的形式
  • 530、二叉搜索树的最小绝对差
  • 2020大厂web前端面试常见问题总结
  • 计算机毕业设计 基于Python的人事管理系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档
  • 疾风大模型气象,基于气象数据打造可视化平台
  • SpringBoot框架下校园资料库的构建与优化
  • 鸿蒙开发(NEXT/API 12)【管理应用与Wear Engine服务的连接状态】手机侧应用开发
  • Go-Micro客户端请求报500错误的解决方法
  • 健康信息管理:SpringBoot的创新应用
  • 怎样用python+sqlalchemy获得mssql视图对应物理表关系(二)
  • npm包管理深度探索:从基础到进阶全面教程!