简体   繁体   English

映射列表<KeyValuePair<string,int> &gt; 在 C# 中自定义对象

[英]Mapping List<KeyValuePair<string,int>> to custom object in C#

I have a method that returns List<KeyValuePair<string,int>> .我有一个返回List<KeyValuePair<string,int>> These are column data from different tables in a database depending of the parameters of the call and I would like map then to custom objects depending on the table data returned.这些是来自数据库中不同表的列数据,具体取决于调用的参数,我想根据返回的表数据映射到自定义对象。

As an example is the return list contain data from table 1 with column , (C1, C2, C3, C4)例如,返回列表包含来自表 1 的数据和列(C1, C2, C3, C4)

The possible returned values are可能的返回值是

KeyValPair<C1, ValueOfC1>
KeyValPair<C2, ValueofC2>
etc....

This list should be mapped to a list of CustomC1 where CustomC1 is defined as follow:此列表应映射到 CustomC1 列表,其中 CustomC1 定义如下:

public class CustumC1 { int c1, int c2, int c3, int c4 }

I need to transform the list of the KeyValuePair to the List of CustomC1 .我需要转换list中的KeyValuePairListCustomC1

So I currently have a method definition which is所以我目前有一个方法定义是

List<KeyValuePair<string,int>> MyMethod(int param)

and I want而且我要

List<TResult> MyMethod<TResult> (int param)

below is my original method that needs to be changed to return a supplied object:下面是我的原始方法,需要更改以返回提供的对象:

 private async Task<List<List<KeyValuePair<string, string>>>> GetData(SqlConnection conn)
        {
            List<string> columnNames = new List<string>();
            string sql = CustomQueryString;
            List<List<KeyValuePair<string, string>>> result = new List<List<KeyValuePair<string, string>>>();
            var reader = await new SqlCommand(sql, conn).ExecuteReaderAsync();

            for (int i = 0; i < reader.FieldCount; i++)
            {
                columnNames.Add(reader.GetName(i));
            }

            while (reader.Read())
            {
                List<KeyValuePair<string, string>> resultRecord = new List<KeyValuePair<string, string>>();
                foreach (var columnName in columnNames)
        {
            resultRecord.Add(new KeyValuePair<string, string>(key: columnName, value: reader[columnName].ToString()));
        }
        result.Add(resultRecord);
    }
    return result;
}

Any help will be highly appreciated.任何帮助将不胜感激。

What are you using to read from the database?你用什么从数据库中读取? And how do you map to a List<KeyValuePair<string,int>> ?, As far as I understand you are mapping to a keyValuePair to later map it to a generic object.以及如何映射到List<KeyValuePair<string,int>> ?据我所知,您正在映射到 keyValuePair 以便稍后将其映射到通用对象。 I do not think this is a good approach as you are opening yourself to a lot more complexity with scalability and errors.我认为这不是一个好方法,因为您将面临更多的可扩展性和错误的复杂性。 Better to have a concrete method that return a concret object from the database, as mention in the comments using dapper would be a good solution.最好有一个从数据库返回一个具体对象的具体方法,正如评论中提到的使用 dapper 将是一个很好的解决方案。 Otherwise you can do something like this:否则你可以做这样的事情:

    var modelProperties = modelType.GetProperties();// modelType is your generic object type
    var instance = Activator.CreateInstance(modelType); 

foreach (var property in modelProperties)
{
  var propertyInfo = instance.GetType().GetProperty(property.Name);
  var propertyValue = yourList.FirstOrDefault(x=>x.Key==property.Name);
  propertyInfo.SetValue(instance, ChangeType(propertyValue, propertyInfo.PropertyType), null);       
}

UPDATE更新

For example this code is clear and expressive and tells me what the other developer is doing and I can understand the context of it, it is using Dapper to query and made in CQRS principles:例如,这段代码清晰而富有表现力,告诉我其他开发人员在做什么,我可以理解它的上下文,它使用 Dapper 进行查询并按照 CQRS 原则制作:

 public class GetHousesHandler : IRequestHandler<GetHouses, IEnumerable<House>>
    {
        private readonly IDbConnection _connection;

        public GetHousesHandler(IDbConnection connection)
        {
            _connection = connection ?? throw new ArgumentNullException(nameof(connection));
        }

        public async Task<IEnumerable<House>> Handle(GetHouses request, CancellationToken cancellationToken)
        {
            var sql = $@"
                SELECT StreetName AS {nameof(House.StreetName)}
                  , Number AS {nameof(House.Number)}
                FROM dbo.HouseView
                WHERE Number = @Number;";

            var param = new
            {
                request.Number,
            };

            return await _connection.QueryAsync<House>(
                sql: sql,
                param: param
                );
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM