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

相关文章

通过ibd文件恢复MySql数据的操作方法

《通过ibd文件恢复MySql数据的操作方法》文章介绍通过.ibd文件恢复MySQL数据的过程,包括知道表结构和不知道表结构两种情况,对于知道表结构的情况,可以直接将.ibd文件复制到新的数据库目录并... 目录第一种情况:知道表结构第二种情况:不知道表结构总结今天干了一件大事,安装1Panel导致原来服务

Flask解决指定端口无法生效问题

《Flask解决指定端口无法生效问题》文章讲述了在使用PyCharm开发Flask应用时,启动地址与手动指定的IP端口不一致的问题,通过修改PyCharm的运行配置,将Flask项目的运行模式从Fla... 目录android问题重现解决方案问题重现手动指定的IP端口是app.run(host='0.0.

Seata之分布式事务问题及解决方案

《Seata之分布式事务问题及解决方案》:本文主要介绍Seata之分布式事务问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Seata–分布式事务解决方案简介同类产品对比环境搭建1.微服务2.SQL3.seata-server4.微服务配置事务模式1

mysql关联查询速度慢的问题及解决

《mysql关联查询速度慢的问题及解决》:本文主要介绍mysql关联查询速度慢的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql关联查询速度慢1. 记录原因1.1 在一次线上的服务中1.2 最终发现2. 解决方案3. 具体操作总结mysql

Jmeter如何向数据库批量插入数据

《Jmeter如何向数据库批量插入数据》:本文主要介绍Jmeter如何向数据库批量插入数据方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Jmeter向数据库批量插入数据Jmeter向mysql数据库中插入数据的入门操作接下来做一下各个元件的配置总结Jmete

一文教你解决Python不支持中文路径的问题

《一文教你解决Python不支持中文路径的问题》Python是一种广泛使用的高级编程语言,然而在处理包含中文字符的文件路径时,Python有时会表现出一些不友好的行为,下面小编就来为大家介绍一下具体的... 目录问题背景解决方案1. 设置正确的文件编码2. 使用pathlib模块3. 转换路径为Unicod

Spring MVC跨域问题及解决

《SpringMVC跨域问题及解决》:本文主要介绍SpringMVC跨域问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录跨域问题不同的域同源策略解决方法1.CORS2.jsONP3.局部解决方案4.全局解决方法总结跨域问题不同的域协议、域名、端口

SpringBoot操作MaxComputer方式(保姆级教程)

《SpringBoot操作MaxComputer方式(保姆级教程)》:本文主要介绍SpringBoot操作MaxComputer方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的... 目录引言uqNqjoe一、引入依赖二、配置文件 application.properties(信息用自己

SpringBoot自定义注解如何解决公共字段填充问题

《SpringBoot自定义注解如何解决公共字段填充问题》本文介绍了在系统开发中,如何使用AOP切面编程实现公共字段自动填充的功能,从而简化代码,通过自定义注解和切面类,可以统一处理创建时间和修改时间... 目录1.1 问题分析1.2 实现思路1.3 代码开发1.3.1 步骤一1.3.2 步骤二1.3.3

C#中的 Dictionary常用操作

《C#中的Dictionary常用操作》C#中的DictionaryTKey,TValue是用于存储键值对集合的泛型类,允许通过键快速检索值,并且具有唯一键、动态大小和无序集合的特性,常用操作包括添... 目录基本概念Dictionary的基本结构Dictionary的主要特性Dictionary的常用操作