本文的目的是為了更加深刻的理解反射。
ORM:Object Relational Mapping對象關系映射,是解決了面向對象語言和關系型數據庫不匹配的問題。
ORM是一種思想,實現這種思想的技術有很多,如C#中的Entity Framework,NHibernate,Java中的Hibernate。
新建一個控制台應用程序,添加一個類,Person.cs
1 public class Person
2 {
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;//person
14 //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=1
39 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();