有什么方法可以创建通用映射器来检索对象内的集合?

时间:2019-01-24 15:56:20

标签: c# .net .net-core

我已经使用dapper设置了通用查询执行程序,但是我想知道是否存在使用存储过程为对象包含对象列表创建映射器的方法。

例如: 我需要检索公司和相关产品

public class company
{
    public List<Product> products {get;set;}
}


  public static async Task<List<DTO>> ExecuteQueryAsync<DTO>(string query , object param) where DTO : class, new()
    {
        List<DTO> result = null;

        try
        {
            var connection = new DbConnection().GetConnection();
            if (connection.State == ConnectionState.Closed)
            {
                connection.Open();
            }

            if (connection.State == ConnectionState.Open)
            {
                result = await SqlMapper.QueryAsync<DTO>(connection, query,param) as List<DTO>;
                connection.Close();

            }
        }
        catch (Exception ex)
        {
            throw ex;
        }

        return result;
    }

1 个答案:

答案 0 :(得分:0)

通过向Poco注入处理GridReader的方法,可以使代码更“干净”。

这可以使关注点分离。

“ DataLayer”对象

using Dapper;
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;

namespace MyNamespace.DataLayer
{ 

public class MyCustomObjectData : IMyCustomObjectData
{

    public async Task<ICollection<MyCustomObject>> MyMethodAsync(Func<GridReader, ICollection<MyCustomObject>> handleFunction)
    {
        ICollection<MyCustomObject> returnItems = null;
        string sqlProcedureName = "dbo.uspMyCustomObjectSelectStuff";

        try
        {
            using (IDbConnection dbConnection = /* your code here */)
            {
                DynamicParameters parameters = new DynamicParameters();
                parameters.Add(/* your code here */);
                GridReader gr = await dbConnection.QueryMultipleAsync(sqlProcedureName, parameters, commandType: CommandType.StoredProcedure, commandTimeout: 120);
                if (null != handleFunction)
                {
                    returnItems = handleFunction(gr);
                }
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message, ex);
        }

        return returnItems;
    }
}
}

“ DomainDataLayer”对象

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static Dapper.SqlMapper;

namespace MyNamespace.DomainDataLayer
{    
    public class MyCustomObjectDomainData : IMyCustomObjectDomainData
    {

        public MyCustomObjectDomainData(IMyCustomObjectData crgDataLayer)
        {
            this.MyCustomObjectData = crgDataLayer ?? throw new ArgumentNullException("IMyCustomObjectData is null");
        }

        public async Task<ICollection<MyCustomObject>> MyCustomObjectGetMethodAsync()
        {
            ICollection<MyCustomObject> returnCollection = null;
            /* CALL the datalayer, but INJECT the method to handle the GridReader */
            returnCollection = await this.MyCustomObjectData.MyMethodAsync(this.HandleMyCustomObjectGridReaderResult);
            return returnCollection;
        }

        public ICollection<MyCustomObject> HandleMyCustomObjectGridReaderResult(GridReader gr)
        {
            ICollection<MyCustomObject> returnCollection = null;

            using (gr)
            {
                /*  Get objects from each SELECT statement in the stored procedure */
                returnCollection = gr.Read<MyCustomObject>().ToList();

                /* this would be how to handle a SECOND "select" statement in the stored procedure */
                IEnumerable<MyOtherCustomObjectFromASecondStoredProcedureSelectStatement> otherThings = gr.Read<MyOtherCustomObjectFromASecondStoredProcedureSelectStatement>().ToList();

                /* optionally, you can hand-map the pocos to each other */
                //returnCollection = new MyCustomObjectObjectMapper().MapMultipleMyCustomObject(returnCollection, otherThings);
            }

            return returnCollection;
        }
    }
}