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:
Mapper.Initialize(cfg =>
{
cfg.AddCollectionMappers();
cfg.SetGeneratePropertyMaps<GenerateEntityFrameworkPrimaryKeyPropertyMaps<DbContext>>();
});
AutoMapper adds support for "updating" DbSet collections using this line:
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:
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? 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. Basically they represent a database table and provide query and DML operations for it.
Looks like you want to synchronize the whole table with the DTO list. 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. 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.
Something like this:
await dbSet.LoadAsync();
Mapper.Map(dtoCollection, dbSet.Local);
await context.SaveChangesAsync();