数据库查询 - DataTable转Entity类型数据

当使用Sql语句查询数据库,返回DataSet数据集。

DataSet转化为数据列表,可以通过映射方式直接返回Entity数据列表

新建一个特性类,用于数据库列表列名称映射

LinqToDB提供了一个ColumnAttribute,但是通过反射不方便获取ColumnAttribute
获取CustomAttributes时,虽然可以筛选到指定ColumnAttribute,但是CustomAttributeData不容易转换到ColumnAttribute

var customAttributeDatas = mi.CustomAttributes.Where(i=>i.AttributeType.Name==nameof(ColumnAttribute)).ToList();

以下是自定义的特性类

复制代码
 1     [AttributeUsage(AttributeTargets.Property)]
 2     public sealed class ColumnFieldAttribute : Attribute
 3     {
 4         /// <summary>
 5         /// 表对应的字段名
 6         /// </summary>
 7         public string ColumnName { set; get; }
 8 
 9         public ColumnFieldAttribute(string columnName)
10         {
11             ColumnName = columnName;
12         }
13     }
复制代码

通过反射,将DataTable转换为数据列表

复制代码
 1     /// <summary>
 2     /// 将DataRow/DataTable转换成Entity类型
 3     /// </summary>
 4     public static class DataTableConverter<T> where T : new()
 5     {
 6         /// <summary>
 7         /// 将DataTable转换成Entity列表
 8         /// </summary>
 9         /// <param name="dt"></param>
10         /// <returns></returns>
11         public static List<T> ToList(DataTable dt)
12         {
13             List<T> list = new List<T>(dt.Rows.Count);
14             foreach (DataRow dr in dt.Rows)
15             {
16                 list.Add(ToEntity(dr));
17             }
18             return list;
19         }
20         /// <summary>
21         /// 将DataRow行转换成Entity
22         /// </summary>
23         /// <param name="dr"></param>
24         /// <returns></returns>
25         private static T ToEntity(DataRow dr)
26         {
27             T entity = new T();
28             Type info = typeof(T);
29             var members = info.GetMembers();
30             foreach (var memberInfo in members)
31             {
32                 if (memberInfo.MemberType == MemberTypes.Property)
33                 {
34                     //读取属性上的DataField特性
35                     object[] attributes = memberInfo.GetCustomAttributes(typeof(ColumnFieldAttribute), true);
36                     foreach (var attr in attributes)
37                     {
38                         var dataFieldAttr = attr as ColumnFieldAttribute;
39                         if (dataFieldAttr != null)
40                         {
41                             var propInfo = info.GetProperty(memberInfo.Name);
42                             if (dr.Table.Columns.Contains(dataFieldAttr.ColumnName))
43                             {
44                                 //根据ColumnName,将dataRow中的相对字段赋值给Entity属性
45                                 propInfo.SetValue(entity,
46                                     Convert.ChangeType(dr[dataFieldAttr.ColumnName], propInfo.PropertyType),
47                                     null);
48                             }
49                         }
50                     }
51                 }
52             }
53             return entity;
54         }
55     }
复制代码

 

posted @   唐宋元明清2188  阅读(655)  评论(0编辑  收藏  举报
编辑推荐:
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
点击右上角即可分享
微信分享提示
哥伦布
01:11发布
哥伦布
01:11发布
8°
西北风
2级
空气质量
相对湿度
81%
今天
中雨
3°/15°
周四
大雨
2°/14°
周五
小雨
4°/10°