如何使用 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 => ...)`,您不需要强制转换任何内容...
我想我的代码中遗漏了一些导致此错误的内容: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 => ...)`,您不需要强制转换任何内容...