我已经阅读了许多关于实体框架问题的帖子,其中包含很多对许多人的问题,并且它再次成为了一个痛苦的问题。
Colaborador有一个ICollection of Time和 时间有一个Colaborador的集合
有人说在上下文中添加之前必须附加子实体(对我来说不起作用,Pk错误)。
我正在使用简单的注入器,我的上下文是每个请求。
我的关联表映射如下:
HasMany<Time>(c => c.Times)
.WithMany(t => t.Colaboradores)
.Map(ct =>
{
ct.MapLeftKey("ColaboradorId");
ct.MapRightKey("TimeId");
ct.ToTable("Receptor");
});
它在数据库中创建关联表。 当我尝试插入Colaborador(实体)时,我在其列表中添加一些Times(Teams),添加到DbContext然后SaveChanges()。
当我这样做时,它会创建一个新的Colaborador,在关联表(ids)中正确插入,但也复制时间。
var colaborador = Mapper.Map<ColaboradorViewModel, Colaborador>(colaboradorVm);
List<TimeViewModel> timesVm = new List<TimeViewModel>();
colaboradorVm.TimesSelecionados.ForEach(t => timesVm.Add(_serviceTime.BuscarPorId(t)));
colaborador.Times = Mapper.Map<ICollection<TimeViewModel>, ICollection<Time>>(timesVm);
函数BuscarPorId执行Find方法并返回Time。
我已经发现如果我调用Add命令,实体会将子状态标记为Added,但是如果我尝试附加Time或将状态更改为Unchanged,我会得到一个关键错误......
foreach (var item in colaborador.Times)
{
lpcContext.Set<Time>().Attach(item);
//lpcContext.Entry(item).State = EntityState.Unchanged;
}
有没有办法告诉实体框架不插入特定的孩子?那么只填充主表和关联表吗?
答案 0 :(得分:1)
Mapper.Map
会创建未附加到您的上下文的新Time
个对象,因此您必须将它们作为Unmodified
附加,但是附加它们会因重复PK而导致另一个错误,因为您的上下文是已经跟踪Time
实体的原始副本。使用Find
方法将检索这些跟踪和本地缓存的实体。
查找并使用已附加到您的上下文的实体:
而不是:
colaborador.Times = Mapper.Map<ICollection<TimeViewModel>, ICollection<Time>>(timesVm);
使用:
var times = new List<Time>();
var dbSet = lpcContext.Set<Time>();
foreach( var t in timesVm )
{
var time = dbSet.Find( t.Id );
if( null == time )
{
time = Mapper.Map<TimeViewModel, Time>( t );
}
times.Add( time );
}
collaborador.Times = times;