实体框架6.1:创建父实体时更新子ICollection

如何解决实体框架6.1:创建父实体时更新子ICollection

我必须将数据从源数据库传递到另一个目标数据库,这两个数据都是使用Entity Framework处理的,只是使用了两个不同的DbContexts

这是我的代码:

internal async static Task UploadNewsList(DateTime dataStart,TextWriter logger)
{
    try
    {
        NumberFormatInfo provider = new NumberFormatInfo();
        provider.NumberDecimalSeparator = ".";

        using (BDContentsDataModel buffettiContext = new BDContentsDataModel())
        {
            List<News> newsList = buffettiContext.News.Where(x => x.Online && x.DataPub >= dataStart.Date).ToList();
            using (DirectioDBContext directioContext = new DirectioDBContext())
            {
                foreach(News buffettiNews in newsList)
                {
                    bool hasAuth = false;
                    List<DirectioAutore> listAutori = null;
                    List<DirectioAutore> listAutoriFinal = new List<DirectioAutore>();

                    if (buffettiNews.AutoreList?.Count > 0)
                    {
                        hasAuth = true;
                        listAutori = EntitiesHelper.GetAutoriDirectio(buffettiNews.AutoreList.ToList(),directioContext);
                        foreach (var autore in listAutori)
                        {
                            int dirAuthId = 0;
                            bool exist = false;
                            foreach (var dirAut in directioContext.Autori)
                            {
                                if (dirAut.Nome.IndexOf(autore.Nome,StringComparison.InvariantCultureIgnoreCase) >= 0 &&
                                    dirAut.Cognome.IndexOf(autore.Cognome,StringComparison.InvariantCultureIgnoreCase) >= 0)
                                {
                                    exist = true;
                                    dirAuthId = dirAut.Id;
                                }
                            }
                                //directioContext.Autori.
                                //Where(x => autore.Cognome.ToLowerInvariant().Contains(x.Cognome.ToLowerInvariant()) &&
                                //         autore.Nome.ToLowerInvariant().Contains(x.Nome.ToLowerInvariant())).Any();

                            if (!exist)
                            {
                                directioContext.Autori.Add(autore);
                                directioContext.SaveChanges();
                            }
                            else
                            {
                                autore.Id = dirAuthId;
                            }

                            listAutoriFinal.Add(autore);
                        }
                    }

                    DirectioNews directioNews = EntitiesHelper.CreateDirectioNewsModel(buffettiNews);
                    if (hasAuth)
                        directioNews.AutoreList = listAutoriFinal;

                    if (directioNews == null)
                        throw new Exception("[News] - Trasformazione entità fallita");

                    directioContext.News.Add(directioNews);
                    await directioContext.SaveChangesAsync();
                }
            }
        }
    }
    catch (Exception ex)
    {
        logger.WriteLine(ex.Message);
        throw ex;
    }
}

这是目标DbContext

public class DirectioDBContext : DbContext
{
    public DirectioDBContext() : base("name=DirectioCMSDataModel") { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        // ...
        
        modelBuilder.Entity<DirectioNews>()
            .HasMany(s => s.AutoreList)
            .WithMany(x => x.News)
            .Map(cs =>
            {
                cs.MapLeftKey("Autore_Id");
                cs.MapRightKey("News_Id");
                cs.ToTable("NewsAutore");
            });
    }

    public virtual DbSet<DirectioNews> News { get; set; }
    public virtual DbSet<DirectioVideo> Video { get; set; }
    public virtual DbSet<DirectioMedia> Media { get; set; }
    public virtual DbSet<DirectioAutore> Autori  { get; set; }
    public virtual DbSet<DirectioVideoAutori> VideoAutori { get; set; }
}

这是感兴趣的目标父模型:

[Table("News")]
public partial class DirectioNews
{
    [Key]
    public int Id { get; set; }

    public string Titolo { get; set; }

    public int IdDocType { get; set; }

    public string Abstract { get; set; }

    public string Testo { get; set; }

    [Required]
    public DateTime DataPub { get; set; }

    public int IdUmbraco { get; set; }

    public int CreatedById { get; set; }

    public DateTime CreateDate { get; set; }

    public int? UpdateById { get; set; }
    public DateTime? UpdateDate { get; set; }

    public int? DeletedById { get; set; }
    public DateTime? DeletedDate { get; set; }
    public int? ResumedById { get; set; }
    public DateTime? ResumedDate { get; set; }

    public int? PublishedById { get; set; }
    public DateTime? PublishedDate { get; set; }
    public int? UnpublishedById { get; set; }
    public DateTime? UnpublishedDate { get; set; }

    public DateTime? PublishedFrom { get; set; }
    public DateTime? PublishedTo { get; set; }
    public bool Online { get; set; }
    public bool APagamento { get; set; }
    public int IdConsulenzaOld { get; set; }

    public bool IsDeleted { get; set; }

    public virtual ICollection<DirectioAutore> AutoreList { get; set; }

    public bool IsFromOtherCMS { get; set; } = false;

    public string Name { get; set; }
    public int? NodeId { get; set; }

    public int SortOrder { get; set; } = 0;

    public Guid PlatformGuid { get; set; }

    public Guid SourceGuid { get; set; }

    // Permette l'accesso anche senza login
    public bool FreeWithoutLogin { get; set; }

    // nasconde dalla visualizzazione della lista normale del frontend,visibile solo attraverso l'etichetta campagna
    public bool HideFromList { get; set; }

    #region parametri per riferimenti temporali
    public int? Day { get; set; } = null;
    public int? Month { get; set; } = null;
    public int? Year { get; set; } = null;
    #endregion

    public int? MediaId
    {
        get; set;
    }
}

这是目标子模型

[Table("Autori")]
public class DirectioAutore
{
    [Key]
    public int Id { get; set; }

    public string Nome { get; set; }

    [Required]
    public string Cognome { get; set; }

    public string DescrizioneBreve { get; set; }

    public string Descrizione { get; set; }

    public string Email { get; set; }

    public string Immagine { get; set; }

    public string Tipo { get; set; } // Maschio Femmina Team

    public string Twitter { get; set; }

    public int IdUmbraco { get; set; }

    public bool Online { get; set; }
    public DateTime? PublishedFrom { get; set; }
    public DateTime? PublishedTo { get; set; }
    public int IdOld { get; set; }
    public bool IsDeleted { get; set; }

    public int? NodeId { get; set; }
    public string Name { get; set; }
    public int CreatedById { get; set; } = 1;

    public DateTime CreateDate { get; set; }

    public int? UpdateById { get; set; }
    public DateTime? UpdateDate { get; set; }
    public int? DeletedById { get; set; }
    public DateTime? DeletedDate { get; set; }
    public int? ResumedById { get; set; }
    public DateTime? ResumedDate { get; set; }

    public int? PublishedById { get; set; }
    public DateTime? PublishedDate { get; set; }
    public int? UnpublishedById { get; set; }
    public DateTime? UnpublishedDate { get; set; }

    public string MetaaDescrBreve { get; set; }

    public int? MediaId
    {
        get; set;
    }

    public Guid PlatformGuid { get; set; }

    public Guid SourceGuid { get; set; }

    public string MetaTitle { get; set; }

    public string MetaDescription { get; set; }

    public virtual ICollection<DirectioNews> News { get; set; }
}

EntityFramework生成了此表来处理此many-to-many关系:

many to many rel

保存实体时,它进入catch语句并显示此错误:

INSERT语句与FOREIGN KEY约束“ FK_dbo.NewsAutore_dbo.Autori_Autore_Id”冲突。数据库“ DirectioContentsCMS_Stage_20201102”的表“ dbo.Autori”的列“ Id”中发生了冲突

可能是什么问题?

非常感谢

解决方法

[已解决]

我错误地将LeftKeyRightKey指向了DbContext,他们没有指向正确的FKs

我刚刚倒转FKs

modelBuilder.Entity<DirectioNews>()
    .HasMany(s => s.AutoreList)
    .WithMany(x => x.News)
    .Map(cs =>
    {
        cs.MapLeftKey("Autore_Id");
        cs.MapRightKey("News_Id");
        cs.ToTable("NewsAutore");
    });

代替

modelBuilder.Entity<DirectioNews>()
    .HasMany(s => s.AutoreList)
    .WithMany(x => x.News)
    .Map(cs =>
    {
        cs.MapLeftKey("News_Id");
        cs.MapRightKey("Autore_Id");
        cs.ToTable("NewsAutore");
    });

因为MapLeftKey指向navigation property方法中指定的HasMany父级实体,而MapRightKey指向父级navigation property中指定的WithMany实体。我当时正好相反。

然后我在实际保存新闻以防止多个作者创建后移动了该关联:

// ...

DirectioNews directioNews = EntitiesHelper.CreateDirectioNewsModel(buffettiNews);
if (directioNews == null)
    throw new Exception("[News] - Trasformazione entità fallita");

directioContext.News.Add(directioNews);
directioContext.SaveChanges();

if (hasAuth)
{
    List<int> ids = listAutori.Select(s => s.Id).ToList();
    List<DirectioAutore> r = directioContext.Autori.Where(x => ids.Contains(x.Id)).ToList();
    directioNews.AutoreList = r;
    directioContext.SaveChanges();

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-