为Dapper编写一个类似于EF的Map配置类
引言
最近在用Dapper处理Sqlite。映射模型的时候不喜欢用Attribute配置,希望用类似EF的Map来配置,所以粗略的实现了一个。
实现
首先是主体的配置辅助类型:
using System;
using System.Collections.Concurrent;
using System.Linq.Expressions;
using System.Reflection;
using Dapper;
using DRapid.Utility.Linq.Expressions;
namespace DRapid.Utility.Dapper.Map
{
public class InstanceMapper<T> : InstanceMapper
{
protected InstanceMapper()
: base(typeof(T))
{
}
public static InstanceMapper<T> Config()
{
return new InstanceMapper<T>();
}
public void MapColumn(string columnName, Expression<Func<T, object>> propertySelector)
{
var propertyName = ExpressionHelper.ReadMemberName(propertySelector);
MapColumn(columnName, propertyName);
}
}
public class InstanceMapper : SqlMapper.ITypeMap
{
protected InstanceMapper(Type type)
{
_map = new CustomPropertyTypeMap(type, GetProperty);
_mapDic = new ConcurrentDictionary<string, PropertyInfo>();
_instanceType = type;
}
private CustomPropertyTypeMap _map;
private Type _instanceType;
private ConcurrentDictionary<string, PropertyInfo> _mapDic;
public ConstructorInfo FindConstructor(string[] names, Type[] types)
{
return _map.FindConstructor(names, types);
}
public ConstructorInfo FindExplicitConstructor()
{
return _map.FindExplicitConstructor();
}
public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName)
{
return _map.GetConstructorParameter(constructor, columnName);
}
public SqlMapper.IMemberMap GetMember(string columnName)
{
return _map.GetMember(columnName);
}
public void MapColumn(string columnName, string propertyName)
{
_mapDic.AddOrUpdate(columnName,
key => _instanceType.GetProperty(propertyName),
(key, pro) => _instanceType.GetProperty(propertyName));
}
private PropertyInfo GetProperty(Type type, string columnName)
{
PropertyInfo propertyInfo;
var result = _mapDic.TryGetValue(columnName, out propertyInfo);
return result ? propertyInfo : null;
}
public void Apply()
{
SqlMapper.SetTypeMap(_instanceType, this);
}
public static InstanceMapper Config(Type type)
{
return new InstanceMapper(type);
}
}
}
这里是其中引用的一个辅助方法的实现
public static string ReadMemberName<T>(Expression<Func<T, object>> expression)
{
var body = expression.Body;
/*这里需要考虑转型表达式*/
if (body.NodeType == ExpressionType.Convert)
body = ((UnaryExpression) body).Operand;
Trace.Assert(body.NodeType == ExpressionType.MemberAccess, "表达式必须是成员访问或者是带转型的成员访问");
var accessMember = (MemberExpression) body;
return accessMember.Member.Name;
}
然后是一些链式调用的扩展支持
using System;
using System.Linq.Expressions;
namespace DRapid.Utility.Dapper.Map
{
public static class InstanceMapperExtension
{
public static InstanceMapper<T> Use<T>(this InstanceMapper<T> mapper, string columnName, string propertyName)
{
mapper.MapColumn(columnName, propertyName);
return mapper;
}
public static InstanceMapper<T> Use<T>(this InstanceMapper<T> mapper, string columnName,
Expression<Func<T, object>> propertySelector)
{
mapper.MapColumn(columnName, propertySelector);
return mapper;
}
}
}
调用
由于有静态访问入口,所以配置一般分布在各个类的静态构造函数中,从而防止重复配置。
所以,对于一个dto类型:
public class PointInfo
{
public byte[] Detail { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public int Count { get; set; }
}
可以使用以下配置代码进行配置:
InstanceMapper<PointInfo>.Config()
.Use("STATLG", s => s.Longitude)
.Use("STATLA", s => s.Latitude)
.Use("FREQUERYCOUNT", s => s.Count)
.Use("FREQDB", s => s.Detail)
.Apply();
结束。
为Dapper编写一个类似于EF的Map配置类的更多相关文章
- Java连接MySQL数据库。编写一个应用程序,在主类Test_4类中,通过JDBC访问stu数据库,显示t_student表中的内容(表结构见表1),显示效果自己设计。
题目2:编写一个应用程序,在主类Test_4类中,通过JDBC访问stu数据库,显示t_student表中的内容(表结构见表1),显示效果自己设计.之后,可根据显示的内容进行某条记录的删除(以id为条 ...
- 编写一个应用程序,在主类Test1类中,创建两个链表List<E>对象,分别存储通过键盘输入的字符串内容
题目1:编写一个应用程序,在主类Test1类中,创建两个链表List<E>对象,分别存储通过键盘输入的字符串内容--"chen","wang",&q ...
- property_自己编写一个读取Property文件的Util类
读取property文件的Util类: 所需jar包: 编写PropertiesUtil类: package com.west.util.property; import java.io.InputS ...
- 16.按要求编写Java应用程序。 编写一个名为Test的主类,类中只有一个主方法; 在主方法中定义一个大小为50的一维整型数组,数组名为x,数组中存放着{1, 3,5,…,99}输出这个数组中的所有元素,每输出十个换一行;在主方法中定义一 个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。
//分类 package com.bao; public class Shuchu { int[]yi=new int[50]; String[][]er=new String[10][10]; vo ...
- 按要求编写Java应用程序。 编写一个名为Test的主类,类中只有一个主方法; 在主方法中定义一个大小为50的一维整型数组,数组名为x,数组中存放着{1, 3,5,…,99}输出这个数组中的所有元素,每输出十个换一行;在主方法中定义一 个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。
int[]x=new int [50]; char[][]y=new char[10][10]; int j=1,w=0; for(int i=0;i<50;i++) { x[i]=j; j+= ...
- 编写一个名为Test的主类,类中只有一个主方法; 在主方法中定义一个大小为50的一维整型数组,数组名为x,数组中存放着{1, 3,5,…,99}输出这个数组中的所有元素,每输出十个换一行;在主方法中定义一 个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。
package liu0915; import java.util.Random; public class Test0915sz { public static void main(String[] ...
- 编写一个Filter,除继承HttpServlet类外还需要( )。
A.继承Filter 类 B.实现Filter 接口 C.继承HttpFilter 类 D.实现HttpFilter接口 解答:B
- 【1】按照Django官网,编写一个web app 创建project/配置数据库
1. Creating a project From the command line, cd into a directory where you'd like to store your code ...
- 13)编写一个子类SnakeCtrl来继承基类
1)首先是创建子类SnakeCtrl 2) 添加那个SnakeCtrl子类 3)出来了SnakeCtrl的基本样子 4)简单实现: ①改编那个SnakeCtrl.h中的内容: #pragma ...
随机推荐
- 在VS2010中使用附加进程的方式调试IIS中的页面
h3{background:#333333; } 准备篇-配置IIS环境 在发布网站之前,需要安装iis环境! 之后点击确定即可! 发布网站至IIS-附加到进程调试 1. 用VS2010将 ...
- jquery---helloworld
style.css
- MYSQL 排行类的相关SQL写法,仅供参考
SELECT * FROM () )) b
- asp.net MVC中使用Html.Checkbox提示该字符串未被识别为有效的布尔值错误的解决方法
在asp.net MVC中使用Html.CheckBox提交后出现该字符串未被识别为有效的布尔值错误,或从类型“System.String”到类型“System.Boolean”的参数转换失败. 错误 ...
- JAVA.IO流学习笔记
一.java.io 的描述 通过数据流.序列化和文件系统提供系统输入和输出.IO流用来处理设备之间的数据传输 二.流 流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数 ...
- asterisk 语音文件转换
Centos wav to sln sox foo-in.wav -t raw -r 8000 -s -2 -c 1 foo-out.sln 当前目录下所有语音wav文件 转换成sln for a i ...
- [Entity Framework] MySQL @ Entity Framework 6
原文 [Entity Framework] MySQL @ Entity Framework 6 要让MySQL能够用EF6,我花了一点时间,在此记录一下 安装元件 在设定档加入Provider 安装 ...
- Javascript中的函数
Javascript中的函数 1.什么是函数 函数是被命名的,独立的,完成特定功能的代码段.其可能给调用它的程序返回值,我们把这个代码段就称之为"函数". 被命名的:函数大部分都是 ...
- opencv 手写选择题阅卷 (四)Android端 手机应用开发
opencv 手写选择题阅卷 (四)Android 手机应用开发 在PC端把代码调通以后开始开发Android 手机应用,因为主要功能代码为C++代码,所以需要通过NDK编译,JAVA通过JNI方式调 ...
- XPOSED-LUA
转载说明 本篇文章可能已经更新,最新文章请转:http://www.sollyu.com/xposed-lua/ 说明 Xposed Lua Module 是一个Xposed的模块,他有下面的优点 本 ...