如何解决实体框架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
关系:
INSERT语句与FOREIGN KEY约束“ FK_dbo.NewsAutore_dbo.Autori_Autore_Id”冲突。数据库“ DirectioContentsCMS_Stage_20201102”的表“ dbo.Autori”的列“ Id”中发生了冲突
可能是什么问题?
非常感谢
解决方法
[已解决]
我错误地将LeftKey
和RightKey
指向了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 举报,一经查实,本站将立刻删除。