如何使用 autoMapper 列出数据表?

How to use autoMapper for datatables to list?

我想我的代码中遗漏了一些导致此错误的内容:AutoMapperMappingException: Missing type map configuration or unsupported mapping.这是我第一次尝试使用 autoMapper 从数据表中填充我的 dto。所以我从 How do I use automapper to map a dataset with multiple tables 中找到了一个例子。所以这是我的代码:

public class ContractController : ApiController
    {
        private readonly IMapper _mapper;

        public ContractController()
        {
            var mapperConfig = new MapperConfiguration(x =>
                x.CreateMap<IDataReader, ContractListDto>());
            _mapper = mapperConfig.CreateMapper();
        }

        [Route("api/Sales/ContractsList")]
        [HttpGet]
        public IHttpActionResult  Get()
        {
            var salesHelper = new SalesHelper(enmSaleDocType.enmSaleDocType_SaleContract,
                enmSaleAfterSaleMode.enmSaleAfterSaleMode_Sale,
                enmSaleOperationType.enmSaleOperationType_Sales);
            var saleDataTable = salesHelper.GetSales();
            IEnumerable<ContractListDto> contractsDto = null;
            using (var saleDataReader = saleDataTable.CreateDataReader())
            {
                 contractsDto = _mapper.Map<IEnumerable<ContractListDto>>(saleDataReader);
            }
            
            
            return Ok(contractsDto);
        }
    }

我正在使用 api2 dotnet 框架和 automapper 版本 10。所以我无法在 globol.asax 中初始化 automapper。所以我尝试从构造函数中实现这一点,正如您在我的代码中看到的那样。(我可能在那里做错了什么!)。最后我在这里得到错误:

using (var saleDataReader = saleDataTable.CreateDataReader())
            {
                 contractsDto = _mapper.Map<IEnumerable<ContractListDto>>(saleDataReader);
            }

当我尝试映射时。感谢阅读。

您不能使用 Automapper,因为它会在此处查看一个对象的属性,在此处查看另一个对象的属性,并将它们复制过来。 DataRow 没有任何有趣的属性

当您加载弱类型的基本数据表时:

var myDataTable = new DataTable();
myDataDapter.Fill(myDatatable);

您有一组 DataRow 对象。当您想要从数据行中提取数据项时,可以通过多种方式获取它,但根进程始终相同;您通过将索引器传递给集合并强制转换结果,从它所在的对象数组中获取它:

var row1 = myDatatable.Rows[0];

var personName = row1["PersonName"] as string; 

写同样的东西有多种替代方法,但最终这些数据只是存在于一个数组中,并由 string/int 索引,它需要强制转换才有用。一个 DataRow 没有 PersonName 属性 那 returns 一个字符串; AUtomapper 旨在与 PersonName 属性 一起使用 returns 一个字符串。

正如 Panagiotis 在评论中指出的那样,您需要对数据行进行一些操作以使其具有属性,但是您为准备一个随后可以与 Automapper 一起使用的对象所付出的努力,您不妨跳过 Automapper 并将值直接分配给目标对象

示例

//no
class Person{ 
  public string PersonName 
}
...
foreach(DataRow ro in someDt)
  var p = new Person();
  p.PersonName = ro["PersonName"] as string;

  var p = mapper.Map<PersonDto>(p);
  

创建一个人 class 并分配给它的 PersonName 只是为了让 Automapper 有一些东西可以映射到 PersonDto -> 毫无意义!新建一个PersonDto直接赋值就可以了


我们可以通过一些更省力的方式来执行同样的事情,我想这可能有一个用例。如果您想将数据集添加到您的项目中,您可以向其添加一个新的数据表并在其中指定属性的名称和类型。在代码中,它本身就变成了 class,具有 Automapper 可以使用的属性。实际上,这只是 Visual Studio 编写了一堆代码,例如:

class PersonRow: DataRow

  public string PersonName {
    get{
      return this["PersonName"] as string;
    }
...

即in 为您继承基础 DataRow 并添加属性。这是创建仍然像 DataTable/DataRow 一样工作的数据实体表示的一种省力方式(因为它是继承的)..所以数据适配器/ ado.net 可以填充它,然后你可以使用它命名属性

如果你迫不及待地想使用automapper,我会选择它;让 VS 为您编写这段无聊的代码“创建一个命名的 属性 来访问对象的内部数组并转换结果”。这张图片中的每一个都是基本的 DataTable/DataRow,使用命名属性进行了增强:

(来自文档)

它们比基本数据表更好用,您可以直接使用 linq 查询它们 (personDataTable.Select(x => ...)`,您不需要强制转换任何内容...