鉴于我有两个班,Foo和Bar:
public class Foo
{
private readonly List<Bar> _bars = new List<Bar>();
public int Id { get; private set; }
public string Name { get; private set; }
public IEnumerable<Bar> Bars => _bars;
public void AddBar(Bar bar)
{
_bars.Add(bar);
}
public static Foo Create(string name)
{
return new Foo { Name = name };
}
private Foo() { }
}
public class Bar
{
public int Id { get; private set; }
public string Description { get; private set; }
public static Bar Create(string description)
{
return new Bar { Description = description };
}
}
带有2个相应的DTO,
public class BarDto
{
public int Id { get; set; }
public string Description { get; set; }
}
public class FooDto
{
public int Id { get; set; }
public string Name { get; set; }
public List<BarDto> Bars { get; set; }
public FooDto()
{
Bars = new List<BarDto>();
}
}
还有一个AutoMapper / AutoMapper.Collection.EntityFrameworkCore设置
var config = new MapperConfiguration(cfg =>
{
cfg.AddCollectionMappers();
cfg.UseEntityFrameworkCoreModel<DemoContext>();
cfg.CreateMap<BarDto, Bar>().EqualityComparison((src, dest) => src.Id == dest.Id);
cfg.CreateMap<FooDto, Foo>().ForMember(dest => dest.Bars, opt =>
{
opt.MapFrom(s => s.Bars);
opt.UseDestinationValue();
}).EqualityComparison((src, dest) => src.Id == dest.Id);
});
我有一个用例,传入的FooDto可能包含我尝试通过以下方式处理的Bars集合中的插入,附加,更新和删除的项目:
但是下面的代码产生一个InvalidOperationException
异常,指出“ 无法跟踪实体类型为'Bar'的实例,因为已经跟踪了另一个键值为'{Id:1}'的实例。在附加现有实体时,请确保仅附加一个具有给定键值的实体实例“
var fooToUpdate = db.Foos.Include(_ => _.Bars).FirstOrDefault(_ => _.Id == fooDto.Id);
mapper.Map(fooDto, fooToUpdate);
db.SaveChanges();
我的理解是,因为我为EqualityComparison
映射设置了BarDto -> Bar
,它应该更新被跟踪的实体,并且保存操作应该成功,因为它引用了相同的对象?
我不确定我是用错误的方式还是只是在配置中缺少某些东西。
更新
似乎我面临的问题可能与github上的this问题有关。