Abp中ef操作新增重复子级数据问题

2024-04-12 20:44

本文主要是介绍Abp中ef操作新增重复子级数据问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在偶然开发中,导入的多条数据中,可能都存在同一个字段生成主外键关联子级数据的逻辑,此时循环去生成子级数据,会导致重复添加子级数据,有点绕吧,那就那实例说吧

如下:实现导入两条论文数据,论文中有起草人和所在单位,而起草人和所在单位是多对多关系,

这里讲下额外题,多表之间的关系:

  1. 一对一:外键+主键,主键和主键匹配(一对一关系的表会直接安排成一张表)
  2. 一对多,多对一:主键+外键
  3. 多对多:通过中间表连接两张或多张表直接的联系

所以在论文循环时,会遇到多个起草人关联的是同一个企业,企业名称一样,本该是一条数据,但是却关联了多次,且id也会不一样,就会导致在数据库插入起草人数据时,会关联插入多次同一个企业信息,这就导致了重复的企业数据

input.ForEach(s =>{s.DataSources = SystemConstants.StandardSource;var enterprises = MapToEnterprises(s.Affiliations, companys, enterpriseList);companys.AddRange(enterprises);var talents = MapToTalents(s.Talents, enterprises, newTalents, exsitTalents);newTalents.AddRange(talents);var domain = new Standard().SetId(GuidGenerator.Create());SetStandard(s, domain, talents, true);domains.Add(domain);//增加企业或创新平台成果关系var platFormList = s.Affiliations.Where(m => m.EntityType == SystemConstants.innovationplatform).ToList();var plats = MapToPlatforms(platFormList, platForms, innovationPlatforms);innovationPlatforms.AddRange(plats);platMappings.AddRange(ScientficResultAddEInnoList(domain.Id, enterprises, plats));
});

 此处是之前的企业数据,由于这两条论文中的起草人都存在同一个人和所属企业,如上面的excel模板总起草人都有"河南大学-王清北"以及 所在单位”河南大学“,则就导致会在循环生成河南大学企业时会生成两遍

/// <summary>
/// 转化企业实体
/// </summary>
/// <param name="dtos"></param>
/// <param name="enterprises"></param>
/// <returns></returns>
private List<Enterprise> MapToEnterprises(List<SRInnoPlatEpriseDo> dtos, List<Enterprise> newEnterprises, List<Enterprise> enterprises)
{var es = new List<Enterprise>();var existEs = enterprises.Where(s => dtos.Select(d => d.Name).Contains(s.EnterpriseName)).ToList();es.AddRange(existEs);var newEs = dtos.Where(s => s.EntityType == SystemConstants.Enterprise && !enterprises.Select(e => e.EnterpriseName).Contains(s.Name)).Select(s => new Enterprise(GuidGenerator.Create(), s.Name, false, "-", "-", SystemConstants.ImportSource)).ToList();es.AddRange(newEs);return es.Distinct().ToList();
}/// <summary>
/// 转化人才实体
/// </summary>
/// <param name="dtos"></param>
/// <param name="enterprises"></param>
/// <param name="enterpriseList"></param>
/// <returns></returns>
private List<Talent> MapToTalents(List<TalentBaseDo> dtos, List<Enterprise> enterprises,List<Talent> newExistTalents, List<Talent> existTalent = null)
{List<Talent> talents = new List<Talent>();dtos.ForEach(s =>{var items = s.Name.Split('-');var enterprise = enterprises.FirstOrDefault(e => e.EnterpriseName == items[0]);var talent = existTalent.FirstOrDefault(t => t.Name == items[1] && t.EnterpriseName == items[0]);var newTalent = newExistTalents.FirstOrDefault(t => t.Name == items[1] && t.EnterpriseName == items[0]);if (talent != null){talents.Add(talent);}else if (newTalent != null){talents.Add(newTalent);}else{var newTelent = new Talent().SetId(GuidGenerator.Create()).SetName(items[1]).SetEnterpriseName(items[0]).SetJobTitle(string.Empty).SetArea(string.Empty).SetIsGreen(false);newTelent.Enterprise = new List<Enterprise>();newTelent.Enterprise.Add(enterprise);talents.Add(newTelent);}});return talents.Distinct().ToList();
}

最简单的解决方式就是每次循环记录下生成的企业信息插入到全局对象中,然后再在每次处理转化企业实体时,过滤下上次已生成的企业信息,直接用上次生成的企业信息,不再重新生成,

代码修改如下:

/// <summary>
/// 转化企业实体
/// </summary>
/// <param name="dtos"></param>
/// <param name="enterprises"></param>
/// <returns></returns>
private List<Enterprise> MapToEnterprises(List<SRInnoPlatEpriseDo> dtos, List<Enterprise> newEnterprises, List<Enterprise> enterprises)
{var es = new List<Enterprise>();var existEs = enterprises.Where(s => dtos.Select(d => d.Name).Contains(s.EnterpriseName)).ToList();var newExistEs = newEnterprises.Where(s => dtos.Select(d => d.Name).Contains(s.EnterpriseName)).ToList();es.AddRange(existEs);es.AddRange(newExistEs);var newEs = dtos.Where(s => s.EntityType == SystemConstants.Enterprise && !enterprises.Select(e => e.EnterpriseName).Contains(s.Name)&& !newEnterprises.Select(e => e.EnterpriseName).Contains(s.Name)).Select(s => new Enterprise(GuidGenerator.Create(), s.Name, false, "-", "-", SystemConstants.ImportSource)).ToList();es.AddRange(newEs);return es.Distinct().ToList();
}

经测试

        虽然每个起草人都关联了新创建的id=1的这条还未真实插入到数据库的企业,abp中ef会自动判断只插入一条id=1的企业,第二条及之后的起草人都会关联这一条id=1的企业,而不会每次都重新插入,之前的方式因为同一个企业生成了多个id,导致每次插入起草人时,关联的子级企业也会重新再插入

这篇关于Abp中ef操作新增重复子级数据问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/898190

相关文章

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

SpringBoot集成Milvus实现数据增删改查功能

《SpringBoot集成Milvus实现数据增删改查功能》milvus支持的语言比较多,支持python,Java,Go,node等开发语言,本文主要介绍如何使用Java语言,采用springboo... 目录1、Milvus基本概念2、添加maven依赖3、配置yml文件4、创建MilvusClient

kali linux 无法登录root的问题及解决方法

《kalilinux无法登录root的问题及解决方法》:本文主要介绍kalilinux无法登录root的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录kali linux 无法登录root1、问题描述1.1、本地登录root1.2、ssh远程登录root2、

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

SpringValidation数据校验之约束注解与分组校验方式

《SpringValidation数据校验之约束注解与分组校验方式》本文将深入探讨SpringValidation的核心功能,帮助开发者掌握约束注解的使用技巧和分组校验的高级应用,从而构建更加健壮和可... 目录引言一、Spring Validation基础架构1.1 jsR-380标准与Spring整合1

Python 中的 with open文件操作的最佳实践

《Python中的withopen文件操作的最佳实践》在Python中,withopen()提供了一个简洁而安全的方式来处理文件操作,它不仅能确保文件在操作完成后自动关闭,还能处理文件操作中的异... 目录什么是 with open()?为什么使用 with open()?使用 with open() 进行

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

SpringBatch数据写入实现

《SpringBatch数据写入实现》SpringBatch通过ItemWriter接口及其丰富的实现,提供了强大的数据写入能力,本文主要介绍了SpringBatch数据写入实现,具有一定的参考价值,... 目录python引言一、ItemWriter核心概念二、数据库写入实现三、文件写入实现四、多目标写入

Linux ls命令操作详解

《Linuxls命令操作详解》通过ls命令,我们可以查看指定目录下的文件和子目录,并结合不同的选项获取详细的文件信息,如权限、大小、修改时间等,:本文主要介绍Linuxls命令详解,需要的朋友可... 目录1. 命令简介2. 命令的基本语法和用法2.1 语法格式2.2 使用示例2.2.1 列出当前目录下的文