繁体   English   中英

C# 如何在没有 ORM 的情况下从 RDBMS 填充对象列表

[英]C# how to populate list of objects from RDBMS without ORM

我想从 DataTable 中填充对象列表,而不是逐列显式分配数据元素,也不使用 ORM。 使用 Dapper(一个小型 ORM),可以传递一个 POCO(普通对象)列表,并让它根据 POCO 的“形状”自动匹配来自查询的“单元格”。 我想使用 DataTable object 做类似的事情。 有没有办法在不使用 Dapper 的情况下镜像该功能? 我想可以使用反射,但是要让反射可靠地工作通常需要“火箭科学”,尤其是在调试方面。 性能是一个相对次要的问题。

public class Employee
{
    public string lastName { get; set; }
    public string firstAndMidName { get; set; }
    public int employeeNumber { get; set; }
    public int salary { get; set; }
}
// ...
public void runSample()
{
    List<Employee> employeeList = new List<Employee>();
    DataTable myDat = queryRDBMS("select * from Employees");  // typical query API (simplified)
    employeeList = convertDataTableToList(myDat, modelClass: Employee);  // the missing part
}

(更新)

using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;

public static class DataTableExtensions
{
    public static List<T> MapToList<T>(this DataTable dt)
    {
        string currentPropName = string.Empty;

        try
        {
            List<T> list = new List<T>();
            T obj = default(T);

            if (dt?.Rows?.Count > 0)
            {
                foreach (DataRow row in dt.Rows)
                {
                    obj = Activator.CreateInstance<T>();
                    foreach (PropertyInfo prop in obj.GetType().GetProperties())
                    {
                        //  Check has column in case we have extension property
                        if (!dt.HasColumn(prop.Name)) continue;
                        currentPropName = prop.Name;

                        if (!object.Equals(row[prop.Name], DBNull.Value))
                        {
                            //  Need to check object type boolean here because return result from db type will be ulong64 which can't convert to bool
                            if (IsBoolean(prop))
                            {
                                prop.SetValue(obj, Convert.ToBoolean(row[prop.Name]), null);
                            }
                            else
                            {
                                prop.SetValue(obj, row[prop.Name], null);
                            }
                        }
                    }

                    list.Add(obj);
                }
            }

            return list;
        }
        catch (Exception ex)
        {
            throw new Exception($"Error occured while converting object '{currentPropName}' from data table to obj class ", ex);
        }
    }

    private static bool IsBoolean(PropertyInfo prop)
    {
        return prop.PropertyType == typeof(bool) || prop.PropertyType == typeof(bool?);
    }

    public static bool HasColumn(this DataTable dt, string columnName)
    {
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            if (dt.Columns[i].ColumnName.Equals(columnName, StringComparison.InvariantCultureIgnoreCase)) return true;
        }

        return false;
    }
}

暂无
暂无

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

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