• 手写ORM


    ORM

    对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。

    在.NET中我门常见的ORM框架有EF,轻量级的ORM Dapper,不管是哪一种框架,他的功能都是一样的,根据对象的映射,将我们写sql这部分转换为操作实体类来完成相应的增删改查。今天我们通过写一个简单的ORM来帮助我们更深层次的了解ORM

    一.准备对应的实体类

        [Table("Size")]
        public class Size
        {
            [Column("Name")]
            public string Name { get; set; }
            public string Type { get; set; }
        }

    二.定义相应的特性

    这写特性主要用来标记类名和属性名,当数据库中的类名与实体类不一致时,可以通过特性标记来对应我们在特性中写的名字。

    //定义基类 
    public class BaseAttribute : Attribute
        {
            public static string strName = null;
            public BaseAttribute(string name)
            {
                strName = name;
            }
            public string GetName()
            {
                return strName;
            }
        }
    
     public class TableAttribute:BaseAttribute
        {
            public TableAttribute(string name):base(name)
            {
               
            }
         
        }
    
      public class ColumnAttribute:BaseAttribute
        {
            public ColumnAttribute(string name):base(name)
            {
             
            }
        }

    三.编写获取特性的方法(主要用来获取标记的表名和列名)

       public static class AttributeFunc
        {
            //标记实体类名
            public static string GetTableMappingName(this Type type) //扩展方法
            {
                if (type.IsDefined(typeof(BaseAttribute),true))
                {
                    TableAttribute attr = type.GetCustomAttribute<TableAttribute>();
                    return attr.GetName(); //获取特性中的名字
                }
                else
                {
                    return type.Name;     //特性中没有标记时则采用类名
                }
            }
            //标记属性
            public static string GetColumnMappingName(this MemberInfo info)
            {
                if (info.IsDefined(typeof(BaseAttribute), true))
                {
                    ColumnAttribute attr = info.GetCustomAttribute<ColumnAttribute>();
                    return attr.GetName();
                }
                else
                {
                    return info.Name;
                }
            }
        }

    四.写一个简单的查询

      public List<T> FindAll<T>()
            {
                Type type = typeof(T);
                // string clumnString = string.Join(",", type.GetProperties().Select(x => $"[{x.Name}]"));
                //这里将x.Name替换为x.GetColumnMappingName也就是上面写的获取特性的方法。根据判断是否标记特性来取特性名。这里使用了一个扩展方法,所以能直接通过类型打点调用
                string clumnString = string.Join(",", type.GetProperties().Select(x => $"[{x.GetColumnMappingName()}]"));
                string sql = $"select {clumnString} from {type.GetTableMappingName()}";  //拼装sql
                //string sql = $"select {clumnString} from {type.Name}";
    
                using (SqlConnection connection = new SqlConnection(_connectionString))
                {
                    using (SqlCommand cmd = new SqlCommand(sql, connection))
                    {
                        try
                        {
                            connection.Open();
                            SqlDataReader reader = cmd.ExecuteReader();
                            List<T> list = new List<T>();
                            while (reader.Read())
                            {
                                T t = (T)Activator.CreateInstance(type);//创建对象
                                foreach (var prop in type.GetProperties())
                                {
                                    prop.SetValue(t, reader[prop.Name] is DBNull?null: reader[prop.Name]); //属性赋值
                                }
                                list.Add(t);
                            }
                            return list;
                           
                        }
                        catch (System.Data.SqlClient.SqlException e)
                        {
                            connection.Close();
                            throw e;
                        }
                    }
                }
            }
  • 相关阅读:
    python测试开发django-115.Paginator分页器展示table表格数据
    python面试题-如"上海 深圳 深圳 上海",要求输入一个匹配模式,比如: aabb,判断是否符合
    python测试开发django-114.ModelForm中局部钩子(clean_)和全局钩子校验
    python测试开发django-113.使用Bootstrap框架
    MySQL将查询的结果作为update更新的数据,且在原字段数据后 CONCAT拼接(lej)
    MongoDB和Redis的区别是什么
    【精选】由浅入深带你吃透MQ原理与应用场景
    mysql 往表中某个字段的字符串后追加字符串
    mongodb 安装及使用
    Redis和MongoDB的区别(面试受用)
  • 原文地址:https://www.cnblogs.com/HTLucky/p/13157992.html
Copyright © 2020-2023  润新知