不管出于什么原因,有时候框架人员摒弃了NH或EF,而使用原生数据库访问对象。

为了优美的编程,用上我写的轻量级映射扩展方法吧

目的:将SqlDataReader自动转换成T类型

代码如下:

    /// <summary>
/// 提供将SqlDataReader转成T类型的扩展方法
/// </summary>
public static class SqlDataReaderEx
{
private static object _obj = new object();
/// <summary>
/// 属性反射信息缓存 key:类型的hashCode,value属性信息
/// </summary>
private static Dictionary<int, Dictionary<string, PropertyInfo>> propInfoCache = new Dictionary<int, Dictionary<string, PropertyInfo>>(); /// <summary>
/// 将SqlDataReader转成T类型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="reader"></param>
/// <returns></returns>
public static T To<T>(this SqlDataReader reader)
where T : new()
{
if (reader == null || reader.HasRows == false) return default(T); var res = new T();
var propInfos = GetFieldnameFromCache<T>(); for (int i = ; i < reader.FieldCount; i++)
{
var n = reader.GetName(i).ToLower();
if (propInfos.ContainsKey(n))
{
PropertyInfo prop = propInfos[n];
var IsValueType = prop.PropertyType.IsValueType;
object defaultValue = null;//引用类型或可空值类型的默认值
if (IsValueType) {
if ((!prop.PropertyType.IsGenericType)
||(prop.PropertyType.IsGenericType&&!prop.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))))
{
defaultValue = ;//非空值类型的默认值
}
}
var v = reader.GetValue(i);
prop.SetValue(res, (Convert.IsDBNull(v) ? defaultValue : v), null);
}
} return res;
} private static Dictionary<string, PropertyInfo> GetFieldnameFromCache<T>()
{
Dictionary<string, PropertyInfo> res = null;
var hashCode = typeof(T).GetHashCode();
var filedNames = GetFieldname<T>();
lock (_obj)
{
if (!propInfoCache.ContainsKey(hashCode))
{
propInfoCache.Add(hashCode, filedNames);
}
}
res = propInfoCache[hashCode];
return res;
} /// <summary>
/// 获取一个类型的对应数据表的字段信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
private static Dictionary<string, PropertyInfo> GetFieldname<T>()
{
var res = new Dictionary<string, PropertyInfo>();
var props = typeof(T).GetProperties();
foreach (PropertyInfo item in props)
{
res.Add(item.GetFieldName(), item);
}
return res;
} /// <summary>
/// 将SqlDataReader转成List<T>类型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="reader"></param>
/// <returns></returns>
public static List<T> ToList<T>(this SqlDataReader reader)
where T : new()
{
if (reader == null || reader.HasRows == false) return null;
var res = new List<T>();
while (reader.Read())
{
res.Add(reader.To<T>());
}
return res;
} /// <summary>
/// 获取该属性对应到数据表中的字段名称
/// </summary>
/// <param name="propInfo"></param>
/// <returns></returns>
public static string GetFieldName(this PropertyInfo propInfo)
{
var fieldname = propInfo.Name;
var attr = propInfo.GetCustomAttributes(false);
foreach (var a in attr)
{
if (a is DataFieldAttribute)
{
fieldname = (a as DataFieldAttribute).Name;
break;
}
}
return fieldname.ToLower();
}
}

在项目中再也需要reader["fieldname"]这样的惹人厌的写法了

换言之,只需要这样写:

 Model model=SqlDataReader.To<Model>(); 

基本原理当然少不了反射,实体的属性可以用DataField特性标记在数据表中的字段名称,否则与属性同名,字段名称不区分大小写。

DataField特性是自己写的,只有一个Name属性。

    public class DataFieldAttribute : Attribute
{
public DataFieldAttribute()
{ }
public DataFieldAttribute(string name)
{
m_name = name;
}
private string m_name = null; public string Name { get { return m_name; } set { m_name = value; } }
}

是不是很方便,虽然重复造轮子了,但是即使用了原生数据库访问对象,又轻松了转换了实体,带来的方便性可以弥补一切。

记得点【推荐】

性能测试:

与OrmLite对比:

从图中看出,在测试1000次的时候,本文的扩展方法比OrmLite的方法快1263ms,测试多次效率均与该结果基本相符。

Test测试源码如下:

即使用ADO.NET,也要轻量级实体映射,比Dapper和Ormlite均快的更多相关文章

  1. 未找到具有固定名称“System.Data.SQLite”的 ADO.NET 提供程序的实体框架提供程序

    用户代码未处理 System.InvalidOperationException   HResult=-2146233079   Message=未找到具有固定名称"System.Data. ...

  2. asp.net EF6.0中出现未找到具有固定名称“System.Data.SqlClient”的 ADO.NET提供程序的实体框架提供程序解决办法

    出现的错误信息如下所示: 指定的架构无效.错误:  DataModel.ssdl(2,2) : 错误 0152: 未找到具有固定名称“System.Data.SqlClient”的 ADO.NET 提 ...

  3. 关于使用Entity Framework时遇到的问题 未找到具有固定名称“System.Data.SqlClient”的 ADO.NET 提供程序的实体框架提供程序。请确保在应用程序配置文件的“entityFramework”节中注册了该提供程序

    问题描述: 使用Entity Framework获取数据时报以下错误: 未找到具有固定名称“System.Data.SqlClient”的 ADO.NET 提供程序的实体框架提供程序.请确保在应用程序 ...

  4. 释怀我的诺亚尔 不用EF框架,完成完美实体映射,且便于维护!(AutoMapper,petapoco)

    释怀我的诺亚尔   不用EF框架,完成完美实体映射,且便于维护!(AutoMapper,petapoco) 最近,需要搭建一个新项目,在需求分析时确定数据库中需要创建多个存储过程.所以如果还是用原来E ...

  5. ASP.NET Core扩展库之实体映射

    在分层设计模式中,各层之间的数据通常通过数据传输对象(DTO)来进行数据的传递,而大多数情况下,各层数据的定义结构大同小异,如何在这些定义结构中相互转换,之前我们通过使用AutoMapper库,但Au ...

  6. 8.2 使用Fluent API进行实体映射【Code-First系列】

    现在,我们来学习怎么使用Fluent API来配置实体. 一.配置默认的数据表Schema Student实体 using System; using System.Collections.Gener ...

  7. 开源实体映射框架EmitMapper介绍

    开源实体映射框架EmitMapper介绍   综述       EmitMapper是一个开源实体映射框架,地址:http://emitmapper.codeplex.com/.       Emit ...

  8. EntityFramework 实体映射到数据库

    EntityFramework实体映射到数据库 在Entity Framework Code First与数据表之间的映射方式实现: 1.Fluent API映射 通过重写DbContext上的OnM ...

  9. EF Code First:实体映射,数据迁移,重构(1)

    一.前言 经过EF的<第一篇>,我们已经把数据访问层基本搭建起来了,但并没有涉及实体关系.实体关系对于一个数据库系统来说至关重要,而且EF的各个实体之间的联系,实体之间的协作,联合查询等也 ...

随机推荐

  1. SE16N使用方案总结

    SAP中直接修改表.视图的Tcode有SE16N和SM30. 另外,在EHP5版本及其更高的版本中,激活编辑功能是不被允许的,不过程序中是通过一个判断语句来限制的,可以通过将相关的判断值判断前加断点, ...

  2. Sharepoint学习笔记—习题系列--70-576习题解析 -(Q147-Q151)

    Question  147 Your company has an existing SharePoint 2010 public-facing Web site. The Web site runs ...

  3. Menu创建菜单

    菜单是用户界面中最常见的元素之一,使用非常频繁,在Android中,菜单被分为如下三种,选项菜单(OptionsMenu).上下文菜单(ContextMenu)和子菜单(SubMenu),今天这讲是O ...

  4. 机器人聊天的小Demo

    先来张图,看看我们要做成什么样的效果.很简单的一个发送消息接收消息的界面,那怎么实现的呢,毫无疑问,是ListView的多布局了,右边显示我们发送消息的条目,左边显示要接收消息的条目.下面是一个Edi ...

  5. React Native 红屏之Could not connect to development server.

    React Native 是目前最火的开发框架,其他不说了,上Bug. 按照  React Native iOS环境搭建 高级版 在mac上  搭建 React Native  环境,运行 项目 若出 ...

  6. couchDB文档

    每个文档都是自包含的数据单元,是一系列数据项的集合. 每个数据项都有一个名称与对应的值,值既可以是简单的数据类型,如字符串.数字和日期等:也可以是复杂的类型,如有序列表和关联对象. 每个文档都有一个全 ...

  7. ORA-00824: cannot set sga_target due to existing internal settings, see alert log for more information

    这篇文章是上篇文章”Expdp 导数错误 ORA-00832”的延续,前几天工作比较忙.累,直到今天才整理发出来.这个数据库实例的参数设置比较诡异其实是有原因的,由于这台数据库服务器系统是32位,数据 ...

  8. Linux系统查看系统是32位还是64位方法总结

    这篇博客是总结.归纳查看Linux系统是32位还是64位的一些方法,很多内容来自网上网友的博客.本篇只是整理.梳理这方面的知识,方便自己忘记的时候随时查看. 方法1:getconf LONG_BIT ...

  9. SQL SERVER 作业浅析

    作业介绍 SQL SERVER的作业是一系列由SQL SERVER代理按顺序执行的指定操作.作业可以执行一系列活动,包括运行Transact-SQL脚本.命令行应用程序.Microsoft Activ ...

  10. 深入解析SQL Server并行执行原理及实践(上)

    在成熟领先的企业级数据库系统中,并行查询可以说是一大利器,在某些场景下他可以显著的提升查询的相应时间,提升用户体验.如SQL Server, Oracle等, Mysql目前还未实现,而Postgre ...