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的更多相关文章

  1. Java学习笔记之使用反射+泛型构建通用DAO

    PS:最近简单的学了学后台Servlet+JSP.也就只能学到这里了.没那么多精力去学SSH了,毕竟Android还有很多东西都没学完.. 学习内容: 1.如何使用反射+泛型构建通用DAO. 1.使用 ...

  2. 【C# 反射泛型】

    C# 反射泛型 摘自:http://www.itwis.com/html/net/c/20110411/10175.html C#泛型反射和普通反射的区别,泛型反射和普通反射的区别就是泛型参数的处理上 ...

  3. Javaweb学习笔记——(二十七)——————泛型、泛型的通配符、反射泛型信息、反射注解、注解

    泛型     1.泛型类:具有一个或多个类型变量的类,称之为泛型类 class A<T>{ } 2.在创建泛型实例时,需要为其类型变量赋值 A<String> a = new ...

  4. 【译】9. Java反射——泛型

    原文地址:http://tutorials.jenkov.com/java-reflection/generics.html ===================================== ...

  5. JAVA常用基础知识点[继承,抽象,接口,静态,枚举,反射,泛型,多线程...]

    类的继承 Java只支持单继承,不允许多重继承- 一个子类只能有一个父类- 一个父类可以派生出多个子类这里写图片描述子类继承了父类,就继承了父类的方法和属性.在子类中,可以使用父类中定义的方法和属性, ...

  6. C#中反射泛型 CreateInstance

    假设1我有个类叫SortClass,类中有个BubbleSort(int[] array)用于给数组进行排序. 假设2我有个类叫SortT<T>,类中有个BubbleSort(T[] ar ...

  7. DataReader反射泛型对象

    昨天听同学说,要把DataReader对象转成实体对象,要写一个通用的方法.想了下用反射应该可以做到.项目中一般都是用第三方组件来做数据访问层,如,Nhibernate.ef等.于是自己想写个简单例子 ...

  8. C#反射の反射泛型

    C#反射の反射详解(点击跳转)C#反射の反射接口(点击跳转)C#反射反射泛型接口(点击跳转)C#反射の一个泛型反射实现的网络请求框架(点击跳转) 接上篇. 自定义一个泛型类(继承于接口) public ...

  9. Java下的框架编程(反射,泛型,元数据,CGLib,代码动态生成,AOP,动态语言嵌入)

    Java 虽然没有动态语言般暴起,但仍然天连天,水接水的生出好多框架技术---反射(reflection),泛型(generics),元数据(annotation),proxies(proxy/cgl ...

随机推荐

  1. js正则定义支付宝账号、手机号、邮箱

    一.支付宝账号:可以只输入数字.字母.字母(数字)+数字(字母),其中只字母中可以含有@._或者.也可以三者都可以包含并且可以在任意位置,限制:小于等于30位(可根据需求自定义范围): let  zh ...

  2. 关于爬虫的日常复习(10)—— 实战:使用selenium模拟浏览器爬取淘宝美食

  3. latex之在windows环境下能够在latex中使用中文

    今天要把前段时间的实验用英语先记录下来,自己就想根据原来会议的模版弄一个简易的页面(英语),突然想到之前用英文模板时是不能输入中文的,于是想着怎么在latex中输入中文,折腾了许久,终于成功了,现在分 ...

  4. Win10如何关闭最近使用文件夹

    如果默认开启了最近使用文件夹功能的话,最近浏览的文件就会被记录下来.所以看完各种教学资料后,并不是关掉或者重启别人就不知道你看了什么. 方法一: Win10怎么关闭最近使用文件夹 如何清理使用痕迹 从 ...

  5. UVA A Spy in the Metro

    点击打开题目 题目大意: 在一个有n个站台的地铁线路里,给你列车通向每相邻两个车站所花费的时间,从0时刻开始,从1号站出发,要在T这个时间点上,到达n号站,给你m1辆从1开到n的列车及其出发时间,和m ...

  6. Ubuntu下配置GitHub

    使用GitHub进行代码托管是如此地方便,原来一直在Windows下进行操作,非常的简单,由于其图形化界面将所有这些都隐藏起来了. 还是不得不吐槽一下自己,非得将自己的系统装为Ubuntu... 言归 ...

  7. python从excel中读取数据传给其他函数使用

    首先安装xlrd库 pip install xlrd 方法1: 表格内容如下: 场景描述,读取该表格A列数据,然后打印出数据 代码何解析如下: import xlrd #引入xlrd库 def exc ...

  8. 使用jmeter做接口测试

    1.启动jmeter. 我们可以找到Jmeter/bin 目录下的jmeter-server这个脚本,运行即可. 在下图打开的Jmeter 页面中,右键“测试计划” -> “添加” -> ...

  9. SpringCloud学习之搭建eureka集群,手把手教学,新手教程

    一.为什么需要集群 上一篇文章讲解了如何搭建单个节点的eureka,这篇讲解如何搭建eureka集群,这里的集群还是本地不同的端口执行三个eureka,因为条件不要允许,没有三台电脑,所以大家将就一下 ...

  10. 用ES7解决异步回调地狱问题

    用了 Promise 其实并没有真正解决回调地狱问题,并且还新增了很多 .then(data => { .... }) 这些很没有意义的 “模板代码”.所以先人们又搞出了generator 和 ...