MapTo() inside of LINQ returning multiple iterations of same data

蓝咒 提交于 2019-12-24 17:24:49

问题


I am using .NET Core with the ASP.NET Boilerplate framework. In some code that I was given to fix, we had a GetAll() method that was supposed to return a collection of rows from the MsSql database. The original code:

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

The problem I was running into with this method, is that it would return the latest row that had not been soft-deleted in the database. However, it would return that same row a number of times equal to the amount of non-deleted rows in that table. So essentially I would get back an IEnumerable that contained all duplicates. To fix this, I changed this method to the following.

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

This (including the commented line) fixed all my issues and returned the correct data. My question is why the first method I mentioned acted in the way that it did. I am not familiar with the MapTo method as I'm used to using ObjectMapper, but from what I found about it I still cannot determine why it behaved in the way that it did.

My DTO has the correct AutoMap data annotation and the DbSet is in the DbContext, if any of that matters.


回答1:


This...

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

...is effectively:

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

In other words, you are mapping every entity to the same DTO.

Since the last entity is mapped last, this means that the DTO mapped from every entity appears to be a duplicate of the DTO mapped from the last entity. But is actually one DTO appearing multiple times.

This would work:

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

Avoid MapTo; use ObjectMapper

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

Since the MapTo extension methods are static, they use AutoMapper's static instance (Mapper.Instance). This is simple and fine for the application code, but you can have problems in unit tests since the static configuration and mapper is shared among different tests, all effecting each other.



来源:https://stackoverflow.com/questions/55145922/mapto-inside-of-linq-returning-multiple-iterations-of-same-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!