欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# 通过反射初探ORM框架的实现原理(详解)

程序员文章站 2023-12-19 20:59:34
背景: 以前学的java进行开发,多用到mybatis,hiberante等orm框架,最近需要上手一个c#的项目,由于不是特别难,也不想再去学习c#的orm框架,所以就...

背景:

以前学的java进行开发,多用到mybatis,hiberante等orm框架,最近需要上手一个c#的项目,由于不是特别难,也不想再去学习c#的orm框架,所以就想着用反射简单的实现一下orm框架的内容,简单的增删改查,没有用到多表之间的联系。

反射:

java和c#中的反射大体相同,主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。我的理解就是可以程序运行时动态的获取对象的属性和方法,并且可以进行与之相关的调用。

首先看一下c#中反射实现方式:

获取type对象,反射操作都需要通过type对象来进行。

通过全限定名来获取 type tp = type.gettype("tjcommon.dao.deriver");
通过类来获取 type tp = typeof(int)

获取到type对象后我们可以通过其构造方法来创建对象

调用无参构造

// 获取类的初始化构造信息
 constructorinfo ct = tp.getconstructor(system.type.emptytypes);
// 调用不带参数的构造器
t newobj = (t)ct.invoke(null);

调用有参构造

//定义参数类型数组
 type[] tps = new type[2];
 tps[0] = typeof(int);
 tps[1] = typeof(string);
 //获取类的初始化参数信息
 constructorinfo ct2 = tp.getconstructor(tps);
 //定义参数数组
 object[] obj = new object[2];
 obj[0] = (object)100;
 obj[1] = (object)"param example";
 //调用带参数的构造器
 exampleclass ex2 = (exampleclass)ct2.invoke(obj);

获得所有公共字段

// 获取到所有公共字段
fieldinfo[] arr = t.getfields(); 
// 给指定的字段赋值 需要传递进来一个对象 newobj
f.setvalue(newobj, r[name]); 

这里就介绍这几个方法,通过反射可以获得类中的所有信息,并且可以进行调用,还可以打破封装(不安全)

练习

下面就是通过反射将从数据库中获取到的结果集自动封装到bean中。无需手动封装

public static t datatoobj(string str)
 {
  string strsql = str;
  dataset ds = sqlcompose.executesqlquery(strsql);
  type t = typeof(t);
  datarow r = ds.tables[0].rows[0]; // 找到一行
  fieldinfo[] arr = t.getfields(); // 返回所有公共字段(public)
  constructorinfo ct = t.getconstructor(system.type.emptytypes);
  t newobj = (t)ct.invoke(null);
  if (r != null)
  {
  foreach (fieldinfo f in arr)// 遍历所有字段
  {
   string name = f.name;
   type type2 = f.fieldtype;
   if (r[name].gettype() != typeof(dbnull))
   {
   string typename = f.fieldtype.name;
   f.setvalue(newobj, r[name]);
   }
  }
  }
  else
  {
  newobj = default(t);
  }
  ds.tables.clear();
  return newobj;
 }

封装到list

public static list<t> datatolist(string str)
  {
   list<t> list = new list<t>();
   string strsql = str;
   dataset ds = sqlcompose.executesqlquery(strsql);
   type t = typeof(t);
   fieldinfo[] arr = t.getfields(); // 返回所有公共字段(public)
   constructorinfo ct = t.getconstructor(system.type.emptytypes);
   foreach (datarow dr in ds.tables[0].rows)
   {
    t newobj = (t)ct.invoke(null);
    foreach (fieldinfo f in arr)// 遍历所有字段
    {
     string name = f.name;
     type type2 = f.fieldtype;
     string typename = f.fieldtype.name;
     if (dr[name].gettype() != typeof(dbnull))
     {
      f.setvalue(newobj, dr[name]);
     }
    }
    list.add(newobj);
   }
   ds.tables.clear();
   return list;
  }

拼接字符串进行insert操作

public static void inserbybean(string tablename, t target)
 {
  stringbuilder sql = new stringbuilder(); // 拼接的sql
  sql.append("insert into "+tablename+"(");
  type t = target.gettype();
  propertyinfo[] ps = t.getproperties();
  for (int i = 0; i < ps.length; i++)
  {
   object obj = ps[i].getvalue(target, null);
   if (obj != null)
   {
    string name = ps[i].name;
    if (i != ps.length - 1)
    {
     sql.append(" " + name + ",");
    }
    else
    {
     sql.append(" " + name + "");
    }
   }
  }
  sql.append(") values(");

  for (int i = 0; i < ps.length; i++)
  {
   object obj = ps[i].getvalue(target, null);
   if (obj != null)
   {
    if (i != ps.length - 1)
    {
     if (ps[i].propertytype == typeof(string) || ps[i].propertytype == typeof(datetime))
     {
      sql.append("'" + obj + "',");
     }
     else {
      sql.append("" + obj + ",");
     }
    }
    else
    {
     if (ps[i].propertytype == typeof(string) || ps[i].propertytype == typeof(datetime))
     {
      sql.append("'" + obj + "')");
     }
     else
     {
      sql.append("" + obj + ")");
     }
    }
   }
  }
  string resultsql = sql.tostring();
  sqlcompose.executesqlnonquery(resultsql);
 }

以上这篇c# 通过反射初探orm框架的实现原理(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

上一篇:

下一篇: