EF 更新大量的数据时出现重复键错误
咨询区
ChsharpNewbie:
当我把大量的数据插入到数据库时 (PostgreSQL 12
和 Entity Framework Core
),我得到了如下的报错。
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]Failed executing DbCommand (197ms) [Parameters=[@p0='?', @p1='?', @p2='?' (DbType = DateTimeOffset), @p3='?'], CommandType='Text', CommandTimeout='30']INSERT INTO "FileInfos" ("FileId", "FileName", "LastModifiedDateTime", "Path")VALUES (@p0, @p1, @p2, @p3);
fail: Microsoft.EntityFrameworkCore.Update[10000]An exception occurred in the database while saving changes for context type 'PostgreSQLConnect.ContextModels.WebhookContext'.Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.---> Npgsql.PostgresException (0x80004005): 23505: duplicate key value violates unique constraint "PK_FileInfos Severity: FEHLERSqlState: 23505MessageText: double key value violates unique constraint »PK_FileInfos«Detail: Detail redacted as it may contain sensitive data. Specify 'Include Error Detail' in the connection string to include this information.SchemaName: publicTableName: FileInfosConstraintName: PK_FileInfosFile: d:\pginstaller_12.auto\postgres.windows-x64\src\backend\access\nbtree\nbtinsert.cLine: 570Routine: _bt_check_unique
这其中一些数据需要被更新,一些数据需要被创建,在一定数据量下这个方法比较稳定,但如果超过阈值后就会抛出如上的错误,我的代码如下:
private async Task SaveFileInfos(FileInfo fileInfo){var foundFileInfo = _context.FileInfos.Where(f => f.FileId == fileInfo.FileId).FirstOrDefault();if (foundFileInfo == null){await _context.FileInfos.AddAsync(fileInfo);}else{foundFileInfo.FileName = fileInfo.FileName;foundFileInfo.LastModifiedDateTime = fileInfo.LastModifiedDateTime;foundFileInfo.Path = fileInfo.Path;}await _context.SaveChangesAsync();}
我的类定义如下:
public class FileInfo : IFileInfo{[Key]public string FileId {get; set;}public string FileName {get; set;}public DateTimeOffset? LastModifiedDateTime {get; set;}public string Path {get; set;}}
Context类如下:
public class WebhookContext : DbContext{public WebhookContext(DbContextOptions<WebhookContext> options) : base(options) { }public DbSet<FileInfo> FileInfos { get; set; }}
然后在 loop 中做数据库保存。
private async Task ConvertAndSaveFiles(IDriveItemDeltaCollectionPage files){ foreach (var file in files){await SaveFileInfos(file.Name, file.Id, file.LastModifiedDateTime, file.ParentReference.Path);}}
请问我这是哪里写的有问题?
回答区
Edd:
我觉得你要做两点修改。
将 FirstOrDefault 改成 FirstOrDefaultAsync。
where 查询也是多余的。
改造后如下:
private async Task SaveFileInfos(FileInfo fileInfo){//update your code to use FirstOrDefaultAsyncvar foundFileInfo = await _context.FileInfos.FirstOrDefaultAsync(f => f.FileId == fileInfo.FileId);if (foundFileInfo == null){await _context.FileInfos.AddAsync(fileInfo);}else{foundFileInfo.FileName = fileInfo.FileName;foundFileInfo.LastModifiedDateTime = fileInfo.LastModifiedDateTime;foundFileInfo.Path = fileInfo.Path;}// move this outside the for loop.// this will round trip to Db in EVERY fileInfo, not an optimal solution.await _context.SaveChangesAsync(); }
考虑到 SaveChangesAsync 是序列化到数据库,可以移到循环体外。
private async Task ConvertAndSaveFiles(IDriveItemDeltaCollectionPage files){ foreach (var file in files){await SaveFileInfos(file.Name, file.Id, file.LastModifiedDateTime, file.ParentReference.Path);}// this will save everything to Db in just 1 round tripawait _context.SaveChangesAsync(); }
点评区
我个人感觉,这里报错的原因是: 本应该全异步的写法里面又掺杂了同步的写法,这是一种很鸡肋的做法,数据量稍微大一些之后就会有各种问题,这也是一个好的经验教训。
EF 更新大量的数据时出现重复键错误相关推荐
- mybatis 插入数据时返回主键
在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:显然,假如主键是你生成后插入的,自然你已经有主键了,显然不需要我们再去获得,所以我们这里处理的是当主键 ...
- 批量插入数据表数据时,主键冲突的解决
2.使用普通的insert into on conflict合并写入,存在写入放大思路: 大量数据,批量插入到数据表中时,很容易造成主键冲突,重复数据有唯一约束插入不进去表中,报错的问题出现. 排查错 ...
- mysql插入时间区间_mybatis插入数据时返回主键以及MySQL根据时间区间查询问题总结...
最近做项目的过程中,在数据库方面遇到了两个问题,一是在插入一条数据的时候需要将该条数据的主键返回.二是根据时间区间进行查询时某一天的数据查询不到,在此总结记录一下. 1.如何在插入一条数据的同时将主键 ...
- SQL Server2000导出数据时包含主键、字段默认值、描述等信息
时经常用SQL Server2000自带的导出数据向导将数据从一台数据库服务器导出到另一台数据库服务器: 结果数据导出了,但表的主键.字段默认值.描述等信息却未能导出,一直没想出什么方法,今天又尝试了 ...
- 通过Navicat for MySQL导入数据时,日期时间错误问题解决办法
通过 Navicat for MySQL数据库连接工具将 Excel 文件导入数据库时,发现日期出现了问题,日期列本来应该是2021/7/16,结果全部变成1900-01-20 问题原因 Navica ...
- mysql using btree_mysql导入数据时提示 USING BTREE 错误解决办法
错误原因: 主要是是MYSQL 5.1的一个BUG,其出现原因是mysql 5.1和mysql 5.0在处理到索引语句时有所区别. 案例: 有时导入mysql会提示如下错误: ERROR 1064 ( ...
- oracle expdp 39002,expdp 导入数据时ORA-39002、ORA-39070错误排查
今天用expdp的时候,报错 [oracle@jcy2 exped]$ expdp \'/as sysdba\' directory=c1 dumpfile=full.dmp full=y logfi ...
- pdo插入mysql数据出错_php中通过pdo插入数据时,sql语句错误?
再次先谢谢各位大佬!! 接下来直接看代码: include 'mysql_ini.php'; $sql_select = "select * from word where word = ? ...
- hibernate saveorupdate mysql_Mysql数据库 hibernate保存数据时,Mysql主键需设定自增,否则报错_MySQL...
Hibernate bitsCN.com 问题的原因很简单,可能有的时候一下想不起来.MARK下. 报错信息如下: org.springframework.jdbc.UncategorizedSQLE ...
最新文章
- 摄像头YUV图像常见数据格式介绍
- SpringCloud中Feign的适配器的实现方案
- 在lamp环境实现nfs中的wordpress使用
- java 写优先锁_Lock读写锁的优先度比较
- 【转】正则基础之——捕获组(capture group)
- python如何安装wordcloud_不知如何利用Python中wordcloud的安装和使用?这里手把手教你...
- Tensorflow学习—— 预创建的 Estimator
- Linux下Zend Framework的“Invalid Controller Specified”问题
- [转载] python函数——字典设置默认值get() 与 setdefault()区别
- Django笔记8(模板引擎)
- Intouch/ifix语音报警系统制作(4-自动发送邮件提醒)
- 37. 使用accumulate或者for_each进行区间统计
- Java高并发架构设计
- STM32 实现光敏传感器
- 软件测试-APP专项测试
- ps2023最新调色滤镜插件exposure图片后期处理工具
- 巴塞尔协议1、2、3内容总结(转)
- VR全景营销实质体验店铺的实际情况
- ofbiz——工作流学习笔记一(xpdl)
- 使用CSS给图片加上角标记
热门文章
- 搞IT的技术人员为什么会如此苦逼
- 跟我学PHP第二篇- 配置Mysql以及PHP WampServer篇(1)
- 图片处理--熔铸特效
- 【转】SMIL基础教程(1)
- linux的HAL库函数,STM32 HAL库 IIC 协议库函数
- [置顶] 动软软代码生成器使用(127.0.0.1)无法看到 SQLServer2008 新附加数据库的 原因 以及 解决方案...
- wampServer配置WWW根目录遇到的坑
- POJ 3617 Best Cow Line
- mysql interval 3 day_Mysql之INTERVAL与DATE_SUB与EXTRACT函数的使用
- Macbook全系列详细分析及购机指南