简体   繁体   English

AutoMapper.Collections.EntityFramework

[英]AutoMapper.Collections.EntityFramework

Asking same question differently! 提出不同的问题!

Its seems clear I need to elaborate on this question because I have no viable responses. 似乎很明显,我需要阐述这个问题,因为我没有可行的答案。

Based on this AutoMapper registration code: 基于此AutoMapper注册代码:

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

AutoMapper adds support for "updating" DbSet collections using this line: AutoMapper使用此行添加了对“更新” DbSet集合的支持:

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

Saving changes through an open context should result in updating the database: 通过打开的上下文保存更改应导致更新数据库:

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

This does nothing! 这什么都不做!

So back to my original question. 回到我原来的问题。 If calling the mapper with the dto and current state of the entity collection returns an updated entity collection based on the comparison Mapping Created here: 如果使用dto和实体集合的当前状态调用映射器,则会根据比较在此处创建的映射返回更新的实体集合:

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

produces entity collection here: 在此处产生实体集合:

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

Am I support to iterate the new collection and update EF manually using this new collection? 我是否支持迭代新集合并使用此新集合手动更新EF? Its not clear what I am suppose to do at this point? 目前尚不清楚我应该做什么? Is this what I am suppose to do with the resulting collection? 这是我应该对结果集合进行的处理吗?

        // 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();

This is my original question. 这是我最初的问题。 If so it seems redundant. 如果是这样,那似乎是多余的。 So I feel like I am missing something. 所以我觉得我缺少一些东西。

I appreciate some useful feedback. 我感谢一些有用的反馈。 Please help! 请帮忙!

Thanks 谢谢

EF DbSet s are not collections. EF DbSet不是集合。 Basically they represent a database table and provide query and DML operations for it. 基本上,它们代表数据库表并为其提供查询和DML操作。

Looks like you want to synchronize the whole table with the DTO list. 看起来您想将整个表与DTO列表同步。 You can do that by loading the whole table locally using the Load or LoadAsync methods, and then Map the DTO collection to the entity DbSet.Local property. 您可以通过使用LoadLoadAsync方法在本地加载整个表,然后将DTO集合Map到实体DbSet.Local属性来实现。 The difference with your attempts is that the Local property is not a simple list, but observable collection directly bound to the context local store and change tracker, so any modification ( Add , Remove ) will be applied to the database. 您尝试的不同之处在于Local属性不是一个简单的列表,而是直接绑定到上下文本地存储和更改跟踪器的可观察集合,因此所有修改( AddRemove )都将应用于数据库。

Something like this: 像这样:

await dbSet.LoadAsync();
Mapper.Map(dtoCollection, dbSet.Local);
await context.SaveChangesAsync();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM