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 工作,工作就完成了。
我知道有几个关于此的主题,但我在插入和更新与 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 工作,工作就完成了。