当前位置: 移动技术网 > IT编程>开发语言>c# > C# 通过反射初探ORM框架的实现原理(详解)

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

2019年07月18日  | 移动技术网IT编程  | 我要评论
背景: 以前学的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框架的实现原理(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网