如厕两毛 发表于 2023-9-22 16:49:36

一个简易的ORM框架的实现(二)

框架目标

什么是框架,框架能做到什么?

把一个方向的技术研发做封装,具备通用性,让使用框架的开发者用起来很轻松。
属性:

[*]通用性
[*]健壮性
[*]稳定性
[*]扩展性
[*]高性能
[*]组件化
[*]跨平台
从零开始-搭建框架


[*]建立项目
[*]主键查询功能开发
[*]绑定实体
一步一步的给大家推导:
一边写一边测试
从零开始--搭建框架

1. 创建项目

首先,创建两个类库一个名为Models保存我们的模型,一个名为DbProxy的类库保存我们对数据库的核心操作。
先进行我们查询功能的编写,暂时不考虑通用性。
public class DbProxyCore
{
    public Commodity GetCommodity(int id)
    {
      string connectionString = "Data Source=10.10.32.242;Initial Catalog=AdvancedCustomerDB;Persist Security Info=True;User ID=sa;Password=*******";
      Commodity commodity = new Commodity();
      using (var connection = new SqlConnection(connectionString))
      {
            connection.Open();

            string sql = @"SELECT
                            ,
                            ,
                            ,
                            ,
                            ,
                            ,
                            FROM . where Id="+id;

            SqlCommand sqlCommand= connection.CreateCommand();
            sqlCommand.CommandText = sql;
            SqlDataReader reader= sqlCommand.ExecuteReader();//数据集的读取器
         
             if (reader.Read())
            {
                commodity.Id = Convert.ToInt32(reader["Id"]);
                commodity.ProductId = Convert.ToInt64(reader["ProductId"]);
                commodity.CategoryId = Convert.ToInt32(reader["CategoryId"]);
                commodity.Title = reader["Title"].ToString();   
                commodity.Price = Convert.ToDecimal(reader["Price"]);
                commodity.Url = reader["Url"].ToString();
                commodity.ImageUrl = reader["ImageUrl"].ToString();                  
            }
            
      }
      return commodity;
    }
}当我们又创建一个其他的model对象的时候,就遇到一个问题,难道我们需要每次都进行不同对象的独有的方法的创建吗?
并不是,这里就可以通过泛型来完成它们独有的方法
暂时的改造
public T Find<T>(int id) where T : new()
{
      string connectionString = """
          Data Source=10.10.32.242;Initial Catalog=AdvancedCustomerDB;Persist Security Info=True;User ID=sa;Password=*********;
          """;
      T obj = new T();
      using (var connection = new SqlConnection(connectionString))
      {
          connection.Open();

          string sql = @"SELECT
                        ,
                        ,
                        ,
                        ,
                        ,
                        ,
                        FROM . where Id=" + id;

          SqlCommand sqlCommand = connection.CreateCommand();
          sqlCommand.CommandText = sql;
          SqlDataReader reader = sqlCommand.ExecuteReader();//数据集的读取器

          if (reader.Read())
          {
            //commodity.Id = Convert.ToInt32(reader["Id"]);
            //commodity.ProductId = Convert.ToInt64(reader["ProductId"]);
            //commodity.CategoryId = Convert.ToInt32(reader["CategoryId"]);
            //commodity.Title = reader["Title"].ToString();
            //commodity.Price = Convert.ToDecimal(reader["Price"]);
            //commodity.Url = reader["Url"].ToString();
            //commodity.ImageUrl = reader["ImageUrl"].ToString();
          }

      }
      return obj;
}
       尝试运行,可以正确的运行,并不报错。
我们要给对象的属性赋值,不能通过new一个对象,直接调用对象的属性赋值;
这里就可以使用到我们的反射技术。
public T Find<T>(int id) where T : new()
{
      string connectionString = """
          Data Source=10.10.32.242;Initial Catalog=AdvancedCustomerDB;Persist Security Info=True;User ID=sa;Password=7ujm&UJM;
          """;
      //T obj = new T();
      Type type = typeof(T);
      object? oResult = Activator.CreateInstance(type);

      using (var connection = new SqlConnection(connectionString))
      {
          connection.Open();

          string sql = @"SELECT
                        ,
                        ,
                        ,
                        ,
                        ,
                        ,
                        FROM . where Id=" + id;

          SqlCommand sqlCommand = connection.CreateCommand();
          sqlCommand.CommandText = sql;
          SqlDataReader reader = sqlCommand.ExecuteReader();//数据集的读取器

          if (reader.Read())
          {
            //commodity.Id = Convert.ToInt32(reader["Id"]);
            //commodity.ProductId = Convert.ToInt64(reader["ProductId"]);
            //commodity.CategoryId = Convert.ToInt32(reader["CategoryId"]);
            //commodity.Title = reader["Title"].ToString();
            //commodity.Price = Convert.ToDecimal(reader["Price"]);
            //commodity.Url = reader["Url"].ToString();
            //commodity.ImageUrl = reader["ImageUrl"].ToString();
            foreach (var prop in type.GetProperties())
            {                        
                prop.SetValue(oResult, reader);
                                                      
            }
          }

      }
      return (T)oResult;
}还有就是sql语句的问题,如何通过T来生成不同的sql语句。
sql语句应该依赖于我们的泛型T,也通过T来动态生成不同的SQl的语句。
public T Find<T>(int id) where T : new()
{
   string connectionString = """
         Data Source=10.10.32.242;Initial Catalog=AdvancedCustomerDB;Persist Security Info=True;User ID=sa;Password=********;
         """;
   //T obj = new T();
   Type type = typeof(T);
   object? oResult = Activator.CreateInstance(type);

   using (var connection = new SqlConnection(connectionString))
   {
         connection.Open();

         List<string> propNameList = type.GetProperties().Select(c => c.Name).ToList();
         string strProps = string.Join(",", propNameList);

         string sql = $"SELECT {strProps} FROM {type.Name} where Id=" + id;
         //以逗号分割的数据库表的字段名称。
      

         SqlCommand sqlCommand = connection.CreateCommand();
         sqlCommand.CommandText = sql;
         SqlDataReader reader = sqlCommand.ExecuteReader();//数据集的读取器

         if (reader.Read())
         {
             foreach (var prop in type.GetProperties())
             {                        
               prop.SetValue(oResult, reader);
                                                      
             }
         }

   }
   return (T)oResult;
}处理DBNULL的问题
prop.SetValue(oResult, reader is DBNull ? null : reader) ;这里还需要考虑如何避免传入如何的实体,导致报错的问题。
使用基类约束就能避免这个问题了。

来源:https://www.cnblogs.com/wenlong-4613615/archive/2023/09/22/17714924.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 一个简易的ORM框架的实现(二)