如何使用autoMapper列出数据表?

问题描述

我想我错过了代码中导致此错误内容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框架和自动映射器版本10,因此无法在globol.asax中初始化自动映射器。所以我尝试从构造函数中实现这一点,就像您在我的代码中看到的那样。(可能我在那里做错了!)。最后,我在这里得到错误

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; 

有多种写同一件事的方法,但是最终这些数据仅存在于数组中,并由字符串/整数索引,因此需要进行转换才能有用。 DataRow没有返回字符串的PersonName属性。 AUtomapper旨在与返回字符串的PersonName属性一起使用。

正如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);
  

所有创建人员类并分配给其PersonName的东西都只是使Automapper可以将其映射到PersonDto->没有意义!只需创建一个新的PersonDto并直接分配值即可


我们可以减少一些精力来完成相同的事情,我想这可能会有用例。如果要向项目中添加数据集,则可以向其中添加新的数据表,并在其中指定属性的名称和类型。然后,在代码中,它自动成为具有Automapper可以使用的属性的类。实际上,这只是Visual Studio在编写一堆代码,例如:

class PersonRow: DataRow

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

即中的继承您的基本DataRow并添加属性。创建数据实体表示形式仍然可以像DataTable / DataRow一样(因为它是继承的)是一种省力的方法。因此,dataadapter / ado.net可以填充它,然后可以使用命名的属性

如果您迫切需要使用自动映射器,那将是我的选择。让VS为您编写此无聊的代码“创建一个访问对象内部数组并强制转换结果的命名属性”。此图中的每件事都是一个基本的DataTable / DataRow,并通过命名属性进行了增强:

https://docs.microsoft.com/en-us/visualstudio/data-tools/walkthrough-creating-a-dataset-with-the-dataset-designer?view=vs-2019(来自文档)

与基础DataTable相比,它们要好得多,您可以直接查询它们(personDataTable.Select(x => ...)`,您不需要强制转换...