AutoMapper.Collections.EntityFramework - PullRequest
0 голосов
/ 04 мая 2018

По-разному задаем один и тот же вопрос!

Кажется очевидным, что мне нужно уточнить этот вопрос, потому что у меня нет жизнеспособных ответов.

На основании этого регистрационного кода 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();

Это мой оригинальный вопрос. Если так, то это кажется излишним. Поэтому я чувствую, что что-то упустил.

Я ценю некоторые полезные отзывы. Пожалуйста, помогите!

Спасибо

1 Ответ

0 голосов
/ 04 мая 2018

EF DbSet s не являются коллекциями. По сути, они представляют таблицу базы данных и предоставляют для нее запросы и операции DML.

Похоже, вы хотите синхронизировать всю таблицу со списком DTO. Вы можете сделать это, загрузив всю таблицу локально, используя методы Load или LoadAsync, а затем Map коллекцию DTO в свойство объекта DbSet.Local. Разница в ваших попытках заключается в том, что свойство Local - это не простой список, а наблюдаемая коллекция, напрямую связанная с локальным контекстным хранилищем и трекером изменений, поэтому любое изменение (Add, Remove) будет применено к базе данных. .

Примерно так:

await dbSet.LoadAsync();
Mapper.Map(dtoCollection, dbSet.Local);
await context.SaveChangesAsync();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...