MapTo () внутри LINQ возвращает несколько итераций одних и тех же данных - PullRequest
1 голос
/ 13 марта 2019

Я использую .NET Core с фреймворком ASP.NET Boilerplate. В некотором коде, который мне дали исправить, у нас был метод GetAll(), который должен был возвращать набор строк из базы данных MsSql. Оригинальный код:

public IEnumerable<GuidelineCategoriesDto> GetAll(bool activeFilter = true)
{
    return _guidelineCategoriesRepo.GetAll().Select(x => x.MapTo(new GuidelineCategoriesDto())).ToList();
}

Проблема, с которой я столкнулся при использовании этого метода, заключается в том, что он возвращает последнюю строку, которая не была удалена из базы данных. Тем не менее, он будет возвращать ту же строку количество раз, равное количеству не удаленных строк в этой таблице. По сути, я бы вернул IEnumerable, который содержал все дубликаты. Чтобы исправить это, я изменил этот метод на следующий.

public IEnumerable<GuidelineCategoriesDto> GetAll(bool activeFilter = true)
{
    // return _guidelineCategoriesRepo.GetAll().Select(x => ObjectMapper.Map<GuidelineCategoriesDto>(x)).ToList();
    return ObjectMapper.Map<IEnumerable<GuidelineCategoriesDto>>(_guidelineCategoriesRepo.GetAll());
}

Это (включая закомментированную строку) исправило все мои проблемы и вернуло правильные данные. Мой вопрос заключается в том, почему первый метод, который я упомянул, действовал таким же образом. Я не знаком с методом MapTo, поскольку я привык использовать ObjectMapper, но из того, что я нашел, я все еще не могу определить, почему он вел себя так, как он.

Мой DTO имеет правильную аннотацию данных AutoMap, а DbSet находится в DbContext, если это имеет значение.

1 Ответ

2 голосов
/ 17 марта 2019

Этот ...

_guidelineCategoriesRepo.GetAll().Select(x => x.MapTo(new GuidelineCategoriesDto())).ToList();

... эффективно:

var dto = new GuidelineCategoriesDto();
_guidelineCategoriesRepo.GetAll().Select(x => x.MapTo(dto)).ToList();

Другими словами, вы отображаете каждую сущность в один и тот же DTO.

Поскольку последний объект отображается последним, это означает, что DTO, сопоставленный с каждым объектом, представляется дубликатом DTO, сопоставленного с последним объектом. Но на самом деле один DTO появляется несколько раз.

Это будет работать:

_guidelineCategoriesRepo.GetAll().Select(x => x.MapTo<GuidelineCategoriesDto>()).ToList();

Избегать MapTo; используйте ObjectMapper

С https://aspnetboilerplate.com/Pages/Documents/Object-To-Object-Mapping#mapto-extension-methods:

Поскольку методы расширения MapTo равны static, они используют статический экземпляр AutoMapper (Mapper.Instance). Это просто и хорошо для кода приложения, но у вас могут возникнуть проблемы в модульных тестах, поскольку статическая конфигурация и преобразователь разделены между различными тестами, все влияют друг на друга.

...