Entity Framework 存储库模式创建或更新多对多

Entity Framework repository pattern create or update many to many

我知道有几个关于此的主题,但我在插入和更新与 Entity Framework 6 的多对多关系时遇到困难,它周围有一个存储库层。

从导航中删除和添加记录 属性(作为一个集合)不会导致对数据库的任何更改(如数据库日志拦截器中所监视的那样):

Resource newResource = resourceForAppointment.FirstOrDefault(x => x.ResourceId == schedulerEvent.ResourceId);
existingAppointment.Resources.Add(newResource);

Resource oldResource = resourceForAppointment.FirstOrDefault(x => x.ResourceId == schedulerEvent.PreviousResourceId);
existingAppointment.Resources.Remove(oldResource);

await this.Repository.UpdateAsync(existingAppointment);

读取数据完美,所以我怀疑它与配置有关,:

[Table("Appointment")]
public partial class Appointment
{
    public Appointment()
    {        
        Resources = new HashSet<Resource>();
    }
    ...

    public virtual ICollection<Resource> Resources { get; set; }
}

这是我在存储库的异步方法中得到的:

 public virtual async Task<TEntity> UpdateAsync(TEntity entity)
 {
      this.Context.Set<TEntity>().Attach(entity);
      this.Context.Entry(entity).State = EntityState.Modified;
      await this.SaveChangesAsync();

      return entity;        
 }

更新简单属性和 1 对 1 导航属性不是问题,只是 1 对多或多对多关系失败。

目前作为解决方法,我正在使用以下代码,我绝对需要摆脱这段糟糕的编码:

   await this.ResourcesRepository.ExecuteSqlAsync($"DELETE FROM AppointmentResource WHERE AppointmentId = {existingAppointment.AppointmentID} AND ResourceID = {schedulerEvent.PreviousResourceId}");
   await this.ResourcesRepository.ExecuteSqlAsync($"INSERT INTO AppointmentResource VALUES({existingAppointment.AppointmentID},{schedulerEvent.ResourceId}) ");

此处其他值得注意的评论包括我使用 Unity MVC 作为我的存储库的引导程序,因此使用 PerRequestLifeTimeManager。然后将此 DbContext 注入到工作单元 class 中,该工作单元使用预定义的 DbContext 创建存储库。因此在请求的生命周期内只有 1 个活动的 DbContext。

有人知道如何解决这个问题吗?

更新:

当我说插入或更新不起作用时,我并不完全准确。创建新约会时,我可以将新记录添加到资源集合中,正如您从这段代码摘录中看到的那样:

// Map scheduler event to appointment
 Appointment newAppointment = Mapper.Map<Appointment>(schedulerEvent);

// Lookup resource by ID and add to new appointment      
Resource resourceForAppointment = await this.ResourcesRepository.FindOneAsync(x => x.ResourceId == schedulerEvent.ResourceId);
newAppointment.Resources.Add(resourceForAppointment);

 // Save to database
 Appointment freshAppointment = await this.Repository.CreateAsync(newAppointment);


public virtual async Task<TEntity> CreateAsync(TEntity entity)
{
   this.Context.Entry(entity).State = EntityState.Added;
   TEntity createdItem = Context.Set<TEntity>().Add(entity);
   await this.SaveChangesAsync();

   return createdItem;
}

我可以由此得出结论,存储库模式不一定会阻止一对多或多对多关系,但我还遗漏了其他东西。希望这更有意义。

我为此提供了一个简单的解决方案:我创建了一个新的 class 组合了多对多关系的 ID。加上一些流利的 api 工作,工作就完成了。