LINQ内部的MapTo()返回相同数据的多次迭代

时间:2019-03-13 15:44:00

标签: linq asp.net-core entity-framework-core automapper aspnetboilerplate

我将.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数据注释,并且DbSetDbContext中,如果有任何重要的话。

1 个答案:

答案 0 :(得分:2)

这个...

_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)。这对于应用程序代码来说既简单又好用,但是由于静态配置和映射器在不同的测试之间共享,因此相互影响,因此在单元测试中可能会遇到问题。