且构网

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

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

更新时间:2023-02-10 08:22:37

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会产生多个ResultSet数据读取器 - 即读者将有几结果集为每个表,但不会保持关系。

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.

因此,为了得到你想要什么,你需要为每个表中创建阅读器,地图中的每个读者不同的集合,然后使用这些结果来创建最终的复杂对象(S)。

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();
            }
        }
    }
}