一步步实现自己的ORM(二)
2015-03-18 17:28
211 查看
在第一篇《一步步实现自己的ORM(一)》里,我们用反射获取类名、属性和值,我们用这些信息开发了简单的INSERT方法,在上一篇文章里我们提到主键为什么没有设置成自增长类型,单单从属性里我们无法识别哪个是主键,今天我们用Attribute来标识列,关于Attribute,引用MSDN里描述
MADN的定义为:公共语言运行时允许添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型、字段、方法和属性等。Attributes和Microsoft .NET Framework文件的元数据(metadata)保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。 我们简单的总结为:定制特性attribute,本质上是一个类,其为目标元素提供关联附加信息,并在运行期以反射的方式来获取附加信息。
简单来说Attribute就是描述类、方法、属性参数等信息的。
可参考《浅析C#中的Attribute》
在这里我们定义2个Attribute,用来描述表和字段。
View Code
大功告成,我们修改下调用代码
MADN的定义为:公共语言运行时允许添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型、字段、方法和属性等。Attributes和Microsoft .NET Framework文件的元数据(metadata)保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。 我们简单的总结为:定制特性attribute,本质上是一个类,其为目标元素提供关联附加信息,并在运行期以反射的方式来获取附加信息。
简单来说Attribute就是描述类、方法、属性参数等信息的。
可参考《浅析C#中的Attribute》
在这里我们定义2个Attribute,用来描述表和字段。
class EntityHelper { private const string connectionString = ""; public static int Insert<T>(T entity) { var type = typeof(T); Dictionary<string, object> parameters = new Dictionary<string, object>(); var properties = type.GetProperties(); string tableName = string.Empty; TableAttribute[] tableAttrs = (TableAttribute[])type.GetCustomAttributes(typeof(TableAttribute), true); if (tableAttrs.Length > 0) { tableName = tableAttrs[0].Name; } else { tableName = type.Name; } /*将所有的列放到集合里*/ List<ColumnAttribute> columns = new List<ColumnAttribute>(); for (int i = 0; i < properties.Length; i++) { var pi = properties[i]; var attrs = (ColumnAttribute[])pi.GetCustomAttributes(typeof(ColumnAttribute), true); if (attrs.Length > 0) { columns.Add(attrs[0]); } } StringBuilder sql = new StringBuilder(); sql.Append("INSERT INTO [").Append(tableName).Append("]("); int paramIndex = 0; for (int i = 0; i < properties.Length; i++) { var pi = properties[i]; var attrs = (ColumnAttribute[])pi.GetCustomAttributes(typeof(ColumnAttribute), true); if (attrs.Length > 0 && attrs[0].IsGenerated == false) { if (paramIndex > 0) sql.Append(","); sql.Append(attrs[0].Name); paramIndex++; } } sql.Append(") VALUES ("); paramIndex = 0; for (int i = 0; i < properties.Length; i++) { var pi = properties[i]; var attrs = (ColumnAttribute[])pi.GetCustomAttributes(typeof(ColumnAttribute), true); if (attrs.Length > 0 && attrs[0].IsGenerated == false) { if (paramIndex > 0) sql.Append(","); sql.Append("@p").Append(paramIndex); parameters.Add("@p" + paramIndex, pi.GetValue(entity, null)); paramIndex++; } } sql.Append(")"); Console.WriteLine(sql); SqlConnection conn = new SqlConnection(connectionString); var cmd = conn.CreateCommand(); cmd.CommandText = sql.ToString(); foreach (var item in parameters) { var pa = cmd.CreateParameter(); pa.ParameterName = item.Key; pa.Value = item.Value ?? DBNull.Value; cmd.Parameters.Add(pa); } conn.Open(); return cmd.ExecuteNonQuery(); } public static int Update<T>(T entity) { var type = typeof(T); Dictionary<string, object> parameters = new Dictionary<string, object>(); var properties = type.GetProperties(); string tableName = string.Empty; TableAttribute[] tableAttrs = (TableAttribute[])type.GetCustomAttributes(typeof(TableAttribute), true); if (tableAttrs.Length > 0) { tableName = tableAttrs[0].Name; } else { tableName = type.Name; } StringBuilder sql = new StringBuilder(); sql.Append("UPDATE [").Append(tableName).Append("] SET "); int paramIndex = 0; for (int i = 0; i < properties.Length; i++) { var pi = properties[i]; var idAttrs = (IdAttribute[])pi.GetCustomAttributes(typeof(IdAttribute), true); if (idAttrs.Length > 0) //如果是主键 跳过 continue; var columnAttrs = (ColumnAttribute[])pi.GetCustomAttributes(typeof(ColumnAttribute), true); if (columnAttrs.Length > 0) { if (paramIndex > 0) sql.Append(","); // 字段 = @p sql.Append(columnAttrs[0].Name).Append("=").Append("@p" + paramIndex); /*参数*/ parameters.Add("@p" + paramIndex, pi.GetValue(entity, null)); paramIndex++; } } sql.Append(" WHERE "); int keyIndex = 0; for (int i = 0; i < properties.Length; i++) { var pi = properties[i]; var idAttrs = (IdAttribute[])pi.GetCustomAttributes(typeof(IdAttribute), true); if (idAttrs.Length > 0) { if (keyIndex > 0) //考虑到有多个主键 sql.Append(" AND "); sql.Append(idAttrs[0].Name).Append("=").Append("@p").Append(paramIndex); /*参数*/ parameters.Add("@p" + paramIndex, pi.GetValue(entity, null)); paramIndex++; keyIndex++; } } Console.WriteLine(sql); SqlConnection conn = new SqlConnection(connectionString); var cmd = conn.CreateCommand(); cmd.CommandText = sql.ToString(); foreach (var item in parameters) { var pa = cmd.CreateParameter(); pa.ParameterName = item.Key; pa.Value = item.Value ?? DBNull.Value; cmd.Parameters.Add(pa); } conn.Open(); return cmd.ExecuteNonQuery(); } public static int DeleteByKey<T>(params object[] values) { var type = typeof(T); Dictionary<string, object> parameters = new Dictionary<string, object>(); var properties = type.GetProperties(); string tableName = string.Empty; TableAttribute[] tableAttrs = (TableAttribute[])type.GetCustomAttributes(typeof(TableAttribute), true); if (tableAttrs.Length > 0) { tableName = tableAttrs[0].Name; } else { tableName = type.Name; } /*将所有的列放到集合里*/ List<IdAttribute> columns = new List<IdAttribute>(); for (int i = 0; i < properties.Length; i++) { var pi = properties[i]; var attrs = (IdAttribute[])pi.GetCustomAttributes(typeof(IdAttribute), true); if (attrs.Length > 0) { columns.Add(attrs[0]); } } if (columns.Count != values.Length) throw new ArgumentException("参数个数和主键数不一致"); StringBuilder sql = new StringBuilder(); sql.Append("DELETE FROM [").Append(tableName).Append("] ").Append(" WHERE "); for (int i = 0; i < columns.Count; i++) { if (i > 0) //考虑到有多个主键 sql.Append(" AND "); sql.Append(columns[i].Name).Append("=").Append("@p").Append(i); /*参数*/ parameters.Add("@p" + i, values[i]); } Console.WriteLine(sql); SqlConnection conn = new SqlConnection(connectionString); var cmd = conn.CreateCommand(); cmd.CommandText = sql.ToString(); foreach (var item in parameters) { var pa = cmd.CreateParameter(); pa.ParameterName = item.Key; pa.Value = item.Value ?? DBNull.Value; cmd.Parameters.Add(pa); } conn.Open(); return cmd.ExecuteNonQuery(); } }
View Code
大功告成,我们修改下调用代码
EntityHelper.Insert(new User() { Email = "abc@123.com", CreatedTime = DateTime.Now }); EntityHelper.Update(new User() { UserId = 1, Email = "new@new.com", CreatedTime = DateTime.Now }); EntityHelper.DeleteByKey<User>(1);
相关文章推荐
- 一步步实现自己的ORM(三)
- 一步步实现自己的ORM(四)
- 一步步实现自己的ORM(五)
- 一步步实现自己的ORM(一)
- 一步步实现自己的ORM
- C#基础系列:实现自己的ORM(构造我自己的ORM)
- C#基础系列:实现自己的ORM(构造我自己的ORM)
- 一步步实现自己的框架系列(四):页面与页面服务的创建
- C#基础系列:实现自己的ORM(反射以及Attribute在ORM中的应用)
- C#基础系列:实现自己的ORM(ORM的基础概念)
- C#基础系列:实现自己的ORM(反射以及Attribute在ORM中的应用)
- 自己编写BuildProvider来实现ORM以及BuildProvider的调试
- C# 自己实现的一套ORM程序附带实体生成工具
- 自己写一个ORM框架--基于注解和反射的ORM增删改查实现
- 一步步实现自己的框架系列(二):插件框架实现
- 一步步实现自己的框架系列(一):初步架构功能设计
- 自己动手打造ORM(五) —实现
- 一步步实现WebServer中间件——自己实现一个线程池
- 一步步实现自己的框架系列(三):客户端服务端通信的实现
- 自己动手写个ORM实现(3)