用反射、泛型 改造SqlHelper
1. 数据准备
public class BaseModel
{
public int Id { set; get; }
} public class Company : BaseModel
{
public string Name { get; set; }
public System.DateTime CreateTime { get; set; }
public int CreatorId { get; set; }
/// <summary>
/// Eleven
/// int?可空字段 既可以是int 也可以是null
/// 数据库设计的时候 字段是可空null
/// </summary>
public int? LastModifierId { get; set; }//Nullable<int>
public DateTime? LastModifyTime { get; set; }
} public class User : BaseModel
{
public string Name { get; set; }
public string Account { get; set; }
public string Password { get; set; }
public string Email { get; set; }
public string Mobile { get; set; }
public int? CompanyId { get; set; }
public string CompanyName { get; set; }
public int State { get; set; }
public int UserType { get; set; }
public DateTime? LastLoginTime { get; set; }
public DateTime CreateTime { get; set; }
public int CreatorId { get; set; }
public int? LastModifierId { get; set; } }
2. 写通用接口方法
public interface IBaseDAL
{
T FindT<T>(int id) where T : BaseModel;
List<T> FindAll<T>() where T : BaseModel;
bool Add<T>(T t) where T : BaseModel;
bool Update<T>(T t) where T : BaseModel;
bool Delete<T>(T t) where T : BaseModel;
}
3. 用泛型、反射 实现接口中的方法
public T FindT<T>(int id) where T : BaseModel
{
Type type = typeof(T);
string sql = $"SELECT {string.Join(",", type.GetProperties().Select(p => $"[{p.Name}]"))} FROM [{type.Name}] WHERE ID={id}";
using (SqlConnection conn = new SqlConnection(ConnectionStringCustomers))
{
SqlCommand command = new SqlCommand(sql, conn);
conn.Open();
var reader = command.ExecuteReader();
if (reader.Read())
{
return this.Trans<T>(type, reader);
}
else
{
return null;//Eleven 数据库没有,应该返回null 而不是一个默认对象
}
}
} private T Trans<T>(Type type, SqlDataReader reader)
{
object oObject = Activator.CreateInstance(type);
foreach (var prop in type.GetProperties())
{
//prop.SetValue(oObject, reader[prop.Name]]);
//Eleven 可空类型,如果数据库存储的是null,直接SetValue会报错的
prop.SetValue(oObject, reader[prop.Name] is DBNull ? null : reader[prop.Name]);
}
public List<T> FindAll<T>() where T : BaseModel
{
Type type = typeof(T);
string sql = $"SELECT {string.Join(",", type.GetProperties().Select(p => $"[{p.Name}]"))} FROM [{type.Name}]"; //你的类名称如果跟命名空间重复了,也不能用
//string sql = ElevenSqlBuilder<T>.FindAllSql;
using (SqlConnection conn = new SqlConnection(ConnectionStringCustomers))
{
SqlCommand command = new SqlCommand(sql, conn);
conn.Open();
var reader = command.ExecuteReader();
List<T> tList = new List<T>();
//object oObject = Activator.CreateInstance(type);
while (reader.Read())
{ tList.Add(this.Trans<T>(type, reader));
}
return tList;
}
}
public bool Add<T>(T t) where T : BaseModel
{ //id是自增的 所以不能新增 Type type = t.GetType(); string columnString = string.Join(",", type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)//不要父类的
//.Where(p=>!p.Name.Equals("Id"))//去掉id--主键约束了
.Select(p => $"[{p.Name}]"));
//string valueColumn = string.Join(",", type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public).Select(p => $"'{p.GetValue(t)}'"));
//引号怎么加---sqlserver 任意值都可以加单引号
//假如都加引号,如果Name的值里面有个单引号,sql变成什么样的 Eleven's sql会错
//还有sql注入风险
//所以要参数化
string valueColumn = string.Join(",", type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)
.Select(p => $"@{p.Name}"));
var parameterList = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)
.Select(p => new SqlParameter($"@{p.Name}", p.GetValue(t) ?? DBNull.Value));//注意可空类型 string sql = $"Insert [{type.Name}] ({columnString}) values({valueColumn})";
using (SqlConnection conn = new SqlConnection(ConnectionStringCustomers))
{
SqlCommand command = new SqlCommand(sql, conn);
command.Parameters.AddRange(parameterList.ToArray());
conn.Open();
return command.ExecuteNonQuery() == ;
//新增后把id拿出来? 可以的,在sql后面增加个 Select @@Identity; ExecuteScalar
}
}
用反射、泛型 改造SqlHelper的更多相关文章
- Java学习笔记之使用反射+泛型构建通用DAO
PS:最近简单的学了学后台Servlet+JSP.也就只能学到这里了.没那么多精力去学SSH了,毕竟Android还有很多东西都没学完.. 学习内容: 1.如何使用反射+泛型构建通用DAO. 1.使用 ...
- 【C# 反射泛型】
C# 反射泛型 摘自:http://www.itwis.com/html/net/c/20110411/10175.html C#泛型反射和普通反射的区别,泛型反射和普通反射的区别就是泛型参数的处理上 ...
- Javaweb学习笔记——(二十七)——————泛型、泛型的通配符、反射泛型信息、反射注解、注解
泛型 1.泛型类:具有一个或多个类型变量的类,称之为泛型类 class A<T>{ } 2.在创建泛型实例时,需要为其类型变量赋值 A<String> a = new ...
- 【译】9. Java反射——泛型
原文地址:http://tutorials.jenkov.com/java-reflection/generics.html ===================================== ...
- JAVA常用基础知识点[继承,抽象,接口,静态,枚举,反射,泛型,多线程...]
类的继承 Java只支持单继承,不允许多重继承- 一个子类只能有一个父类- 一个父类可以派生出多个子类这里写图片描述子类继承了父类,就继承了父类的方法和属性.在子类中,可以使用父类中定义的方法和属性, ...
- C#中反射泛型 CreateInstance
假设1我有个类叫SortClass,类中有个BubbleSort(int[] array)用于给数组进行排序. 假设2我有个类叫SortT<T>,类中有个BubbleSort(T[] ar ...
- DataReader反射泛型对象
昨天听同学说,要把DataReader对象转成实体对象,要写一个通用的方法.想了下用反射应该可以做到.项目中一般都是用第三方组件来做数据访问层,如,Nhibernate.ef等.于是自己想写个简单例子 ...
- C#反射の反射泛型
C#反射の反射详解(点击跳转)C#反射の反射接口(点击跳转)C#反射反射泛型接口(点击跳转)C#反射の一个泛型反射实现的网络请求框架(点击跳转) 接上篇. 自定义一个泛型类(继承于接口) public ...
- Java下的框架编程(反射,泛型,元数据,CGLib,代码动态生成,AOP,动态语言嵌入)
Java 虽然没有动态语言般暴起,但仍然天连天,水接水的生出好多框架技术---反射(reflection),泛型(generics),元数据(annotation),proxies(proxy/cgl ...
随机推荐
- FastJSON将Java对象转为json,日期显示时间戳未格式化解决办法
JSON版本:FastJson Java 对象转换为 JSON 格式 定义以下 Person JavaBean: public class Person { @JSONField(name = &qu ...
- DFT与IDFT
[转]https://blog.csdn.net/mingzhuo_126/article/details/88044390 二.编程实现考滤到DFT和IDFT算法过程中有部分相似,可以把它们合成到一 ...
- XSS基础学习
XSS基础学习 By:Mirror王宇阳 什么是XSS XSS攻击是指在网页中嵌入一段恶意的客户端Js脚本代码片段,JS脚本恶意代码可以获取用户的Cookie.URL跳转.内容篡改.会话劫持--等. ...
- Oracle索引大全
文档结构如下: 前言: Oracle 官方文档对索引的描述真是弱透了,对索引的说明就是一坨……,support也没有很好的资料,下面还是用的官方上的内容经过自己的整理加上网上的资料. 索引类型: 索引 ...
- RocketMQ客户端加载流程
这节介绍RocketMQ客户端的启动流程,即Consumer和Producer的启动流程. 1. 客户端demo 首先先看下客户端的demo Producer: public class Sync ...
- vnpy源码阅读学习(4):自己写一个类似vnpy的UI框架
自己写一个类似vnpy的界面框架 概述 通过之前3次对vnpy的界面代码的研究,我们去模仿做一个vn.py的大框架.巩固一下PyQt5的学习. 这部分的代码相对来说没有难度和深度,基本上就是把PyQt ...
- .net生成荣誉证书
参考:https://blog.csdn.net/ljk126wy/article/details/84299373 采用生成pdf 方式 效果如下: 用adobe acrobat 制作一个模板 ...
- matplotlib 条形图
一.特点 离散数据,数据之间没有直接的关系 二.分类 1.垂直条形图 bar(x, height, width=0.8) # x 为x轴 # height 为y轴 # width 为 条形图的宽度 例 ...
- css 脱离文档流
一.float <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset=&quo ...
- 「4.0」一个人开发一个App,小程序从0到1,布局
一提到布局这个词,我总是索索发抖,不是因为天冷,而是因为布局的目标实在太宏大.古代想雄霸天下的王,就喜欢布局这个,布局那个,结果硬生生把自己的国家给布局没了.至于是哪个君王,我倒可以非常认真,非常坦诚 ...