最最简单的ORM模块(一)

    虽说ORM框架也挺多……但是说来惭愧我并没有在项目中真正用过……,最近想认认真真研究一下

.NET的反射,所以就有一个想写个框架的念头,小弟我从07年毕业一直做.NET平台的软件开发,但是从

09年初才开始接触到一些设计模式、设计思想。而且我打算逐步的记录自己是如何修改这个框架的。

      好了,现在进入正题,现在先仅仅实现一个简单的关系映射,可以取得数据库的数据,以后再慢慢重

构。

      准备工作:数据库,表     

1 CREATE TABLE [dbo].[Man](
2     [ManID] [varchar](50NOT NULL,
3     [ManName] [nvarchar](maxNOT NULL,
4     [ManAge] [nvarchar](maxNOT NULL,
5  CONSTRAINT [PK_Man] PRIMARY KEY CLUSTERED 
6 (
7     [ManID] ASC
8 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]
9 ON [PRIMARY]

 

插入两条数据:

然后现在要做的就是可以取出所有的数据。

既然要实现最简单的最少需要两个功能,一是封装数据库操作,二是实体类与表的关系映射、类属性与

表中字段的映射。对于这种关系映射没有比反射更合适的了。现在就构造两个类来分别映射表与表中的

字段。

 

 1 //映射表 
 2 public class TableAttribute:Attribute
 3     {
 4        public string TableName;
 5 
 6        public TableAttribute(string tableName)
 7        {
 8            this.TableName = tableName;
 9        }
10     }
11 //映射表中的字段,暂时不考虑数据类型对应的问题。
12  public class FieldAttribute : Attribute
13     {
14 
15         public string FieldName;
16 
17         public FieldAttribute(string fieldName)
18         {
19             this.FieldName = fieldName;
20         }
21 
22     }
23 

 

封装的数据库操作类:

 

代码
 public class DBHelper
    {

        
public static SqlConnection myConn;

        
public DBHelper(string connectionString)
        {
            myConn 
= new SqlConnection(connectionString);
        }

        
public static SqlDataReader ExecuteReader(string sql)
        {
            myConn.Open();
            SqlCommand cmd 
= new SqlCommand(sql, myConn);
            SqlDataReader sdr 
= cmd.ExecuteReader(CommandBehavior.CloseConnection);
            
return sdr;

        }

    }

 

实现关系映射的类(核心部分):

 

 1 public class ActiverRecord
 2     {
 3       
 4 
 5        public List<ActiverRecord> GetAllRecord()
 6        {
 7            List<ActiverRecord> listProduct = new List<ActiverRecord>();
 8 
 9            ActiverRecord stanceObj = this;
10 
11            
12            //拼接SQL语句
13            string tableName = "";
14           object [] attrbuteArray  = this.GetType().GetCustomAttributes(true);
15 
16           tableName = ((attrbuteArray[0]) as TableAttribute).TableName;
17           string sql = "SELECT * FROM " + tableName;
18          
19           
20           //取得对应关系
21           Dictionary<stringstring> realiationShip = new Dictionary<stringstring>();
22 
23           foreach (PropertyInfo pInfo in this.GetType().GetProperties())
24           {
25               string PropertyName = pInfo.Name;
26               string FildName = ((FieldAttribute)pInfo.GetCustomAttributes(true)[0]).FieldName;
27               realiationShip.Add(PropertyName, FildName);
28           }
29           Assembly assemble = Assembly.GetAssembly(this.GetType());
30           using (SqlDataReader sdr =DBHelper.ExecuteReader(sql))
31           {
32               while (sdr.Read())
33               {
34                   object manOne=assemble.CreateInstance(this.GetType().FullName);
35                   int i = 0;
36                   foreach (PropertyInfo pOne in manOne.GetType().GetProperties())
37                   {
38                       foreach (object attr in pOne.GetCustomAttributes(true))
39                       {
40                           string filedName = ((FieldAttribute)attr).FieldName;
41                           pOne.SetValue(manOne, sdr[filedName], null);
42                           i++;
43                       }
44                   }
45 
46                   listProduct.Add((ActiverRecord)manOne);
47                  
48               }
49           }
50 
51            return listProduct;
52        }
53     }

 

对该模块的使用:

 

 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             DBHelper dbop = new DBHelper("Data Source=.;Initial Catalog=TestCode;User ID=sa;Password=sa");
 6            
 7             Man man = new Man();
 8             List<ActiverRecord> onelist= man.GetAllRecord();
 9             foreach (ActiverRecord one in onelist)
10             {
11                 Man oneP = (Man)one;
12                 Console.WriteLine("{0}  {1}  {2}",oneP.ManID,oneP.ManName,oneP.ManID);
13             }
14         }
15     }
16 
17     [Table("dbo.Man")]
18     public class Man: ActiverRecord
19     {
20         private string _manID;
21 
22         [Field("ManID")]
23         public string ManID
24         {
25             get { return _manID; }
26             set { _manID = value; }
27         }
28         private string _manName;
29         [Field("ManName")]
30         public string ManName
31         {
32             get { return _manName; }
33             set { _manName = value; }
34         }
35         private string _ManAge;
36 
37         [Field("ManAge")]
38         public string ManAge
39         {
40             get { return _ManAge; }
41             set { _ManAge = value; }
42         }
43  
44     }

 

运行后的输出结果:

这恐怕是简单的的不能再简单实现映射的模块了。

下一次重构的目标:

1.实现简单的基本的CRUD功能。

2.可以实现生成所需SQL的功能。

3.使用泛型来避免不必要的类型转换。

4.希望可以实现类型之间的对应,但是目前还没想到什么好的办法。(望高手赐教!)

小弟我才学疏浅,对于下一步的重构希望高手可以提出建议。

实例下载:

 

 

 

 

posted @ 2010-03-26 10:41  Justin Liu  阅读(1619)  评论(5编辑  收藏  举报