使用Automapper.Collection.EntityFrameworkCore的EF核心集合

时间:2019-10-02 14:57:25

标签: automapper ef-core-3.0 automapper-collections-ef-core

鉴于我有两个班,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集合中的插入,附加,更新和删除的项目:

  1. 从数据库中查找现有实体
  2. 映射从DTO到实体的变化
  3. 将更改保存到数据库

但是下面的代码产生一个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问题有关。

0 个答案:

没有答案