你的位置:首页 > ASP.net教程

[ASP.net教程]写一个MyORM


本文的目的是为了更加深刻的理解反射。

ORM:Object Relational Mapping对象关系映射,是解决了面向对象语言和关系型数据库不匹配的问题。

ORM是一种思想,实现这种思想的技术有很多,如C#中的Entity Framework,NHibernate,Java中的Hibernate。

 

新建一个控制台应用程序,添加一个类,Person.cs

1 public class Person2   {3    public int Id { get; set; }4    public string Name { get; set; }5    public int Age { get; set; }6   }

添加一个类,MyORM.cs

 1 public class MyORM 2   { 3     private static readonly string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString; 4     //假设:表名和类名一致 5     /// <summary> 6     /// 插入一条数据 7     /// </summary> 8     /// <param name="obj">插入的对象</param> 9     /// <returns>受影响函数</returns>10     public int Insert(object obj)11     {12       Type type = obj.GetType();13       string className = type.Name;//person14       //insert into Person(Name,Age)values("哈哈",10)15       PropertyInfo[] props = type.GetProperties();16       List<string> propNames = new List<string>();//属性名列表17       List<string> paraNames = new List<string>();//参数名列表18       List<MySqlParameter> paramters = new List<MySqlParameter>();//参数19       foreach (PropertyInfo prop in props)20       {21         string propName = prop.Name;22         if (propName != "Id")23         {24           propNames.Add(propName);25           paraNames.Add("@" + propName);26          MySqlParameter para=new MySqlParameter(propName,prop.GetValue(obj));27           paramters.Add(para);28         }29       }30       StringBuilder sqlsb = new StringBuilder();31       sqlsb.Append("insert into ").Append(className).Append("(").Append(string.Join(",", propNames)).Append(")values(").Append(string.Join(",", paraNames)).Append(")");32      return MySqlHelper.ExecuteNonQuery(connstr, sqlsb.ToString(), paramters.ToArray());33     }34     //根据Id查询35     public object SelectById(Type type, int id)36     {37      object obj= Activator.CreateInstance(type);38       //select * from Person where Id=139      string className = type.Name;40      string sql = "select * from " + className + " where Id=@Id";41      MySqlParameter para = new MySqlParameter("@Id",id);42      DataSet ds= MySqlHelper.ExecuteDataset(connstr, sql, para);43      DataTable table = ds.Tables[0];44      if (table.Rows.Count<=0)45      {46        return null;//没有查到数据47      }48      else if (table.Rows.Count>1)49      {50        throw new Exception("出大问题了");51      }52      DataRow row = table.Rows[0];53      foreach (var prop in type.GetProperties())54      {55        prop.SetValue(obj,row[prop.Name]);56      }57      return obj;58     }59     60   }

这里有一个先决条件:类名要和数据库表名一致

Insert方法实现的是只要传一个类Object就可以将这个类对应的数据添加到数据库表中,主要是通过反射的方法获取类名、属性名和属性值,通过这些拼接sql语句,完成insert操作。

SelectById方法是根据类的Type和属性Id的值,从数据库中查询数据并且赋值给Object.先从数据库中查询数据,通过反射的方法为object的每个属性赋值,返回object.

为了事先规定Type的类型,我们还可以把SelectById方法更改为泛型的方法

 //根据Id查询    public T SelectById<T>( int id) where T:new()//泛型约束有无参的构造函数    {      Type type = typeof(T);      //object obj= Activator.CreateInstance(type);      T obj = new T();      //select * from Person where Id=1      string className = type.Name;      string sql = "select * from " + className + " where Id=@Id";      MySqlParameter para = new MySqlParameter("@Id",id);     DataSet ds= MySqlHelper.ExecuteDataset(connstr, sql, para);     DataTable table = ds.Tables[0];     if (table.Rows.Count<=0)     {       return default(T);//没有查到数据     }     else if (table.Rows.Count>1)     {       throw new Exception("出大问题了");     }     DataRow row = table.Rows[0];     foreach (var prop in type.GetProperties())     {       prop.SetValue(obj,row[prop.Name]);     }     return obj;//T类型的    }

 

在主程序中调用的代码

 1      //插入数据到数据库 2       Person p1 = new Person(); 3       MyORM orm = new MyORM(); 4       p1.Name = "哈哈"; 5       p1.Age = 20; 6       orm.Insert(p1); 7       Console.ReadKey(); 8  9       //根据查询数据10       Person p2 = (Person)orm.SelectById(typeof(Person), 1);11       Console.WriteLine(p2.Name);12       Console.ReadKey();13 14      //泛型的方法查询15      Person P3=orm.SelectById<Person>(1);16      Console.WriteLine(p3.Name);17      Console.ReadKey();