admin

实体框架6多对多要插入重复的行

sql

不应该那么难!我要放弃EF …

我的模特有每周报纸版。每个版本可以有许多分类。每个分类可以出现在一个或多个版本中。我的模特:

public class Classifieds
{ 
  [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public int ClassifiedId { get; set; }
  ...
  public virtual ICollection<EditionModel> Editions { get; set; }
}

public class EditionModel
{
  [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
  public int EditionId { get; set; } // This is YYYYWW, WW = week number
  public Date PublicationDate { get; set; }
  public virtual ICollection<Classifieds> Classifieds { get; set; }
}

OnModelCreating重写:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   modelBuilder.Entity<EditionModel>()
     .Property(z => z.EditionId)
     .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

   modelBuilder.Entity<EditionModel>()
     .HasMany(c => c.Classifieds)
     .WithMany(d => d.Editions)
     .Map(x =>
     {
       x.MapLeftKey("EditionId");
       x.MapRightKey("ClassifiedId");
       x.ToTable("EditionModelClassifieds");
     });
   base.OnModelCreating(modelBuilder);
}

创建分类动作代码(HTTP放置):

public async Task<ActionResult> Create(Classifieds classifieds, int[] EditionList)
{
  var allPubs = PopulateEditionList(); // Current and next 12 editions
  db.Set<Classifieds>().Attach(classifieds);
  db.Entry(classifieds).Collection(x => x.Editions).Load();
  foreach (var p in EditionList)
  {
      var anEd = (from x in allPubs where x.EditionId == p select x).Single();
      classifieds.Editions.Add(anEd);
  }
  ...
  if (ModelState.IsValid)
  {
     var ads = db.Classifieds.Add(classifieds);
     await db.SaveChangesAsync().ConfigureAwait(false);
     return View("Receipt", classifieds);
  }
  ...
}

提交新的分类广告后,我得到

Violation of PRIMARY KEY constraint 'PK_dbo.EditionModels'.  
Cannot insert duplicate key in object 'dbo.EditionModels'.

为什么EF坚持要在EditionModels中插入重复的行,而不是仅将联结表行链接到其中的现有行?我该如何解决?


阅读 129

收藏
2021-06-07

共1个答案

admin

问题在于EditionModel不是上下文的一部分。谢谢您,Slauma为我指明了正确的方向。更正后的“创建操作”为:

...
classifieds.Editions = new List<EditionModel>();
foreach (var p in EditionList)
{
   var ed = await db.EditionModel.FindAsync(p);
   if (ed == null)
      ed = new EditionModel { EditionId = p, PublicationDate = (from q in allPubs where                       q.EditionId == p select q).Single().PublicationDate };
   InsertOrUpdate<EditionModel>(ed);
   classifieds.Editions.Add(ed);
}
...

其余代码如上。

2021-06-07