LINQ内部的MapTo()返回同一数据的多个迭代结果[英] MapTo() inside of LINQ returning multiple iterations of same data

本文是小编为大家收集整理的关于LINQ内部的MapTo()返回同一数据的多个迭代结果的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我将.NET Core与ASP.NET样板框架一起使用.在我被给予修复的某些代码中,我们有一个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中,如果有任何重要的话.

推荐答案

这个...

_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/页/文档/对象对象映射#mapto-extension-methods :

由于MapTo扩展方法是static,因此它们使用Automapper的静态实例(Mapper.Instance).对于应用程序代码来说,这很简单又可以,但是由于静态配置和映射器在不同的测试之间共享,因此您可能会在单元测试中遇到问题.

本文地址:https://www.itbaoku.cn/post/1557067.html

问题描述

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.

推荐答案

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.