实体框架存储库模式创建或更新多对多

时间:2015-09-22 14:23:31

标签: c# entity-framework repository many-to-many one-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注入到工作类单元中,该工作类使用预定义的DbContext创建存储库。因此,在请求的生命周期中,只有1个活动的DbContext存在。

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

更新:

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

// 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;
}

我可以从中得出结论,存储库模式并不一定会阻止一对多或多对多的关系,但是我错过了其他的东西。希望这更有意义。

1 个答案:

答案 0 :(得分:0)

我为此提供了一个简单的解决方案:我创建了一个新的类,它结合了多对多关系的ID。与一些流利的api工作和工作一起完成。