1

以不同的方式问同样的问题!

似乎很清楚我需要详细说明这个问题,因为我没有可行的答案。

基于此 AutoMapper 注册码:

Mapper.Initialize(cfg =>
{
   cfg.AddCollectionMappers();
   cfg.SetGeneratePropertyMaps<GenerateEntityFrameworkPrimaryKeyPropertyMaps<DbContext>>();
 });

AutoMapper 使用这一行添加了对“更新” DbSet 集合的支持:

Mapper.Map<List<DTO>, List<Entity>>(dtoCollection, entityCollection);

通过开放上下文保存更改应导致更新数据库:

using (var context = factory.CreateContext())
{
  Mapper.Map<List<DTO>, List<Entity>>(dtoCollection, await 
  context.dbSet.TolistAsync());
  await context.SaveChangesAsync();
}

这无济于事!

所以回到我原来的问题。如果使用实体集合的 dto 和当前状态调用映射器,则基于此处创建的比较映射返回更新的实体集合:

cfg.SetGeneratePropertyMaps<GenerateEntityFrameworkPrimaryKeyPropertyMaps<DbContext>>();

在此处生成实体集合:

var entities =  Mapper.Map<List<DTO>, List<Entity>>(dtoCollection, await 
context.dbSet.TolistAsync());

我是否支持使用这个新集合手动迭代新集合并更新 EF?目前尚不清楚我应该做什么?这是我想对结果集合做的吗?

        // map dto's to entities
        var entities = Mapper.Map(collection, await dbSet.ToListAsync());

        // add new records
        var toAdd = entities.Where(e => e.Id == 0);
        dbSet.AddRange(toAdd);

        // delete old records   
        var toDelete = entities.Where(entity => collection.All(e => e.Id > 0 && e.Id != entity.Id));
        dbSet.RemoveRange(toDelete);

        // update existing records
        var toUpdate = entities.Where(entity => collection.All(i => i.Id > 0 && i.Id == entity.Id)).ToList();
        foreach (var entity in toUpdate)
        {
            context.Entry(entity).State = EntityState.Modified;
        }

        await context.SaveChangesAsync();

这是我原来的问题。如果是这样,它似乎是多余的。所以我觉得我错过了一些东西。

我感谢一些有用的反馈。请帮忙!

谢谢

4

1 回答 1

3

EFDbSet不是集合。基本上它们代表一个数据库表并为其提供查询和 DML 操作。

看起来您想将整个表与 DTO 列表同步。您可以通过使用LoadorLoadAsync方法在本地加载整个表,然后Map将 DTO 集合加载到实体DbSet.Local属性来做到这一点。与您的尝试不同的是,该Local属性不是一个简单的列表,而是直接绑定到上下文本地存储和更改跟踪器的可观察集合,因此任何修改 ( Add, Remove) 都将应用于数据库。

像这样的东西:

await dbSet.LoadAsync();
Mapper.Map(dtoCollection, dbSet.Local);
await context.SaveChangesAsync();
于 2018-05-04T20:00:18.200 回答