且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用 automapper 映射具有多个表的数据集

更新时间:2023-02-10 08:21:55

IDataReader 映射器是一个非常简单的映射器,它可以从数据读取器中填充一个对象,其中它通过列名映射对象属性.它并非旨在创建具有关系等的复杂数据结构.

IDataReader mapper is very simple one, it can populate an object out of a data reader, where it maps the object properties by column names. It was not designed to create a complex data structures with relations, etc.

此外,DataSet.CreateDataReader 将生成一个多结果集数据读取器 - 即,读取器对于每个表的结果集很少,但它不会保留关系.

Also, the DataSet.CreateDataReader will produce a multiple resultset data reader - i.e. the reader will have few result sets for each table, but it will not preserve the relations.

所以,为了得到你想要的,你需要为每个表创建阅读器,将每个阅读器映射到不同的集合,然后使用这些结果来创建最终的复杂对象.

So, in order to get what you want, you need to create reader for each table, map each reader to different collection, and then use these results to create the final complex object(s).

我在这里提供了一种简单的方法,但您可以尽情发挥,创建自定义解析器等,封装一切.

Here I'm providing the simplistic approach, but you can go wild, and create custom resolvers, etc., to encapsulate everything.

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using AutoMapper;
using NUnit.Framework;

namespace ***Example.Automapper
{
    public class Contact
    {
        public Guid ContactId { get; set; }
        public string Name { get; set; }
        public List<Address> Addresses { get; set; }
    }

    public partial class Address
    {
        public Guid AddressId { get; set; }
        public Guid ContactId { get; set; }
        public string StreetAddress { get; set; }
    }

    [TestFixture]
    public class DatasetRelations
    {
        [Test]
        public void RelationMappingTest()
        {
            //arrange
            var firstContactGuid = Guid.NewGuid();
            var secondContactGuid = Guid.NewGuid();

            var addressTable = new DataTable("Addresses");
            addressTable.Columns.Add("AddressId");
            addressTable.Columns.Add("ContactId");
            addressTable.Columns.Add("StreetAddress");
            addressTable.Rows.Add(Guid.NewGuid(), firstContactGuid, "c1 a1");
            addressTable.Rows.Add(Guid.NewGuid(), firstContactGuid, "c1 a2");
            addressTable.Rows.Add(Guid.NewGuid(), secondContactGuid, "c2 a1");

            var contactTable = new DataTable("Contacts");
            contactTable.Columns.Add("ContactId");
            contactTable.Columns.Add("Name");
            contactTable.Rows.Add(firstContactGuid, "contact1");
            contactTable.Rows.Add(secondContactGuid, "contact2");

            var dataSet = new DataSet();
            dataSet.Tables.Add(contactTable);
            dataSet.Tables.Add(addressTable);

            Mapper.CreateMap<IDataReader, Address>();
            Mapper.CreateMap<IDataReader, Contact>().ForMember(c=>c.Addresses, opt=>opt.Ignore());

            //act
            var addresses = GetDataFromDataTable<Address>(dataSet, "Addresses");
            var contacts = GetDataFromDataTable<Contact>(dataSet, "Contacts");
            foreach (var contact in contacts)
            {
                contact.Addresses = addresses.Where(a => a.ContactId == contact.ContactId).ToList();
            }
        }

        private IList<T> GetDataFromDataTable<T>(DataSet dataSet, string tableName)
        {
            var table = dataSet.Tables[tableName];
            using (var reader = dataSet.CreateDataReader(table))
            {
                return Mapper.Map<IList<T>>(reader).ToList();
            }
        }
    }
}