您的位置:首页 > 运维架构 > 网站架构

基于.NET平台的分层架构实战(九)——数据访问层的第三种实现:基于NBear框架的ORM实现

2011-07-01 10:08 856 查看
  前面的文章讨论了使用SQL语句和存储过程两种数据访问层的实现方式,这一篇里,将讨论使用ORM方式实现数据访问层的方法。

  对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。

  目前.NET平台上有许多ORM框架可供选择,如NBear、NHibernate等等。这里我们选择NBear实现ORM。

  NBear是由博客园的Teddy's Knowledge Base团队开发的一个开源框架,主要用来提高.NET平台的开发效率,其中包含了ORM、IoC、MVP等多个组件,这里仅仅用到其中的ORM功能。关于NBear的详细使用方法本文不再详述,请参考NBear入门教程。NBear的最新版本下载地址为http://files.cnblogs.com/hjf1223/NBearV3.7.2.11_src.rar。

  下面我们一步一步实现数据访问层的ORM实现。

  1.创建实体设计工程

  使用NBear实现ORM功能,首先要创建一个实体设计工程,这个工程最终不会应用到系统中,但是必须通过它来生成NBear实体类以及配置文件。

  首先,我们在解决方案下新建一个工程,名字为NBearEntityDesign,并为这个工程添加到文件NBear.Common.Design.dll的引用,这个文件在NBear文件包的dist目录下。

  完成后,在这个工程下新建一个C#文件,名为EntityDesign.cs,这个文件就是设计文件,根据对实体和数据库的设计,编写完整代码如下:

  EntityDesign.cs

1using System;
2using System.Collections.Generic;
3using System.Text;
4using NBear.Common.Design;
5
6namespace NGuestBook.NBearEntityDesign
7{
8  public interface TAdmin : Entity
9  {
10    [PrimaryKey]
11    int ID { get; }
12    [SqlType("nvarchar(20)")]
13    string Name { get; set; }
14    [SqlType("nvarchar(50)")]
15    string Password { get; set; }
16  }
17
18  public interface TComment : Entity
19  {
20    [PrimaryKey]
21    int ID { get; }
22    [SqlType("ntext")]
23    string Content { get; set; }
24    DateTime Time { get; set; }
25    int MessageID { get; set; }
26  }
27
28  public interface TMessage : Entity
29  {
30    [PrimaryKey]
31    int ID { get; }
32    [SqlType("nvarchar(20)")]
33    string GuestName { get; set; }
34    [SqlType("nvarchar(100)")]
35    string GuestEmail { get; set; }
36    [SqlType("ntext")]
37    string Content { get; set; }
38    DateTime Time { get; set; }
39    [SqlType("ntext")]
40    string Reply { get; set; }
41    [SqlType("nvarchar(10)")]
42    string IsPass { get; set; }
43  }
44}


  设计完后,将这个工程编译备用。

  2.创建NBear专用实体类及配置文件

  在NBear文件包的dist目录下,有一个NBear.Tools.EntityDesignToEntity.exe程序,打开它,点击“Browse”按钮,选择刚才编译生成的NGuestBook.NBearEntityDesign.dll文件,并在Output Namespace文本框里输入相应的命名空间,这里我们应输入“NGuestBook.NBearDAL”。然后点击“Generate Entities”按钮,这时会在底下的文本框里生成NBear专用实体类代码。

  在解决方案下新建一个工程NBearDAL,用于存放所有ORM数据访问层的实现代码。在这个工程下新建Entities.cs,将刚才自动生成的代码覆盖掉这个文件的代码,专用实体类就做好了。

  另外,需要给工程NBearDAL添加到NBear.Common.dll和NBear.Data.dll的引用,这两个文件都在dist目录下。

  点击“Generate Configuration”按钮,这时会生成配置代码。在Web工程下新建文件NBearConfig.xml,将生成的代码复制到这个文件里保存。

  最后还要修改一下Web.config文件。增加如下配置代码:

   <configSections>
    <section name="entityConfig" type="NBear.Common.EntityConfigurationSection, NBear.Common"/>
   </configSections>
   <entityConfig>
    <includes>
     <add key="Sample Entity Config" value="~/NBearConfig.xml"/>
    </includes>
   </entityConfig>


  然后再在<connectionStrings>节点下增加如下项:

[code]   <add name="NBearConnectionString" connectionString="Server=LOCALHOSTSQLEXPRESS;Database=NGuestBook;Uid=WebUser;Pwd=123456" providerName="NBear.Data.SqlServer.SqlDbProvider"/>


  其中connectionString是连接字符串,根据个人不同情况进行修改。这里使用的是SQLServer2005。

  因为数据库在上一篇中已经创建好了,这里就不需要创建数据库了。

  3.编写转换器

  这里出现了一个矛盾:业务逻辑层和表示层需要使用通用的实体类,如AdminInfo,而NBear需要使用专用实体类。怎么解决这个矛盾呢?我这里使用的方法是一个我称之为“转换器”的方法。 即为没一个实体写一个专门的转换器,实现两种实体类的转换。这里以管理员实体为例,这个转换器写在NBearDAL工程下的AdminConvertor.cs文件中。具体代码如下:

  AdminConvertor

1using System;
2using NGuestBook.Entity;
3
4namespace NGuestBook.NBearDAL
5{
6  /**//// <summary>
7  /// 实体类转换器-管理员
8  /// </summary>
9  public sealed class AdminConvertor
10  {
11    /**//// <summary>
12    /// 由普通管理员实体类转化为NBear专用管理员实体类
13    /// </summary>
14    /// <param name="commonEntity">普通实体类</param>
15    /// <returns>NBear专用实体类</returns>
16    public static TAdmin CommonEntityToNBearEntity(AdminInfo commonEntity)
17    {
18      TAdmin nbaerEntity = new TAdmin();
19      nbaerEntity.ID = commonEntity.ID;
20      nbaerEntity.Name = commonEntity.Name;
21      nbaerEntity.Password = commonEntity.Password;
22
23      return nbaerEntity;
24    }
25
26    /**//// <summary>
27    /// 由NBear专用管理员实体类转化为普通管理员实体类
28    /// </summary>
29    /// <param name="nbearEntity">NBear专用实体类</param>
30    /// <returns>普通实体类</returns>
31    public static AdminInfo NBearEntityToCommonEntity(TAdmin nbearEntity)
32    {
33      AdminInfo commonEntity = new AdminInfo();
34      commonEntity.ID = nbearEntity.ID;
35      commonEntity.Name = nbearEntity.Name;
36      commonEntity.Password = nbearEntity.Password;
37
38      return commonEntity;
39    }
40  }
41}


  4.实现数据访问层

  做完上述工作,我们就可以来实现数据访问层了。借助于NBear框架的支持,我们可以非常方便的使用ORM方式访问数据库。关于NBear的细节,这里不再赘述,以管理员为例,具体代码如下:

  AdminDAL.cs

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4using System.Data.Common;
 5using NGuestBook.IDAL;
 6using NGuestBook.Entity;
 7using NBear.Common;
 8using NBear.Data;
 9
10namespace NGuestBook.NBearDAL
11{
12  public class AdminDAL : IAdminDAL
13  {
14    /**//// <summary>
15    /// 插入管理员
16    /// </summary>
17    /// <param name="admin">管理员实体类</param>
18    /// <returns>是否成功</returns>
19    public bool Insert(AdminInfo admin)
20    {
21      Gateway.SetDefaultDatabase("NBearConnectionString");
22      DbTransaction transcation = Gateway.Default.BeginTransaction();
23      try
24      {
25        Gateway.Default.Save<TAdmin>(AdminConvertor.CommonEntityToNBearEntity(admin));
26        transcation.Commit();
27        return true;
28      }
29      catch
30      {
31        transcation.Rollback();
32        return false;
33      }
34      finally
35      {
36        Gateway.Default.CloseTransaction(transcation);
37      }
38    }
39
40    /**//// <summary>
41    /// 删除管理员
42    /// </summary>
43    /// <param name="id">欲删除的管理员的ID</param>
44    /// <returns>是否成功</returns>
45    public bool Delete(int id)
46    {
47      Gateway.SetDefaultDatabase("NBearConnectionString");
48      DbTransaction transcation = Gateway.Default.BeginTransaction();
49      try
50      {
51        Gateway.Default.Delete<TAdmin>(id);
52        transcation.Commit();
53        return true;
54      }
55      catch
56      {
57        transcation.Rollback();
58        return false;
59      }
60      finally
61      {
62        Gateway.Default.CloseTransaction(transcation);
63      }
64    }
65
66    /**//// <summary>
67    /// 更新管理员信息
68    /// </summary>
69    /// <param name="admin">管理员实体类</param>
70    /// <returns>是否成功</returns>
71    public bool Update(AdminInfo admin)
72    {
73      Gateway.SetDefaultDatabase("NBearConnectionString");
74      DbTransaction transcation = Gateway.Default.BeginTransaction();
75      PropertyItem[] properties = {
76        new PropertyItem("Name"),
77        new PropertyItem("Password")
78      };
79      object[] values ={
80        admin.Name,
81        admin.Password
82      };
83      try
84      {
85        Gateway.Default.Update<TAdmin>(properties, values, null, transcation);
86        transcation.Commit();
87        return true;
88      }
89      catch
90      {
91        transcation.Rollback();
92        return false;
93      }
94      finally
95      {
96        Gateway.Default.CloseTransaction(transcation);
97      }
98    }
99
100    /**//// <summary>
101    /// 按ID取得管理员信息
102    /// </summary>
103    /// <param name="id">管理员ID</param>
104    /// <returns>管理员实体类</returns>
105    public AdminInfo GetByID(int id)
106    {
107      Gateway.SetDefaultDatabase("NBearConnectionString");
108      TAdmin tAdmin = Gateway.Default.Find<TAdmin>(TAdmin._.ID == id);
109      return tAdmin == null ? null : AdminConvertor.NBearEntityToCommonEntity(tAdmin);
110    }
111
112    /**//// <summary>
113    /// 按用户名及密码取得管理员信息
114    /// </summary>
115    /// <param name="name">用户名</param>
116    /// <param name="password">密码</param>
117    /// <returns>管理员实体类,不存在时返回null</returns>
118    public AdminInfo GetByNameAndPassword(string name, string password)
119    {
120      Gateway.SetDefaultDatabase("NBearConnectionString");
121      TAdmin tAdmin = Gateway.Default.Find<TAdmin>(TAdmin._.Name == name && TAdmin._.Password == password);
122      return tAdmin == null ? null : AdminConvertor.NBearEntityToCommonEntity(tAdmin);
123    }
124
125    /**//// <summary>
126    /// 按管理员名取得管理员信息
127    /// </summary>
128    /// <param name="name">管理员名</param>
129    /// <returns>管理员实体类</returns>
130    public AdminInfo GetByName(string name)
131    {
132      Gateway.SetDefaultDatabase("NBearConnectionString");
133      TAdmin tAdmin = Gateway.Default.Find<TAdmin>(TAdmin._.Name == name);
134      return tAdmin == null ? null : AdminConvertor.NBearEntityToCommonEntity(tAdmin);
135    }
136
137    /**//// <summary>
138    /// 取得全部管理员信息
139    /// </summary>
140    /// <returns>管理员实体类集合</returns>
141    public IList<AdminInfo> GetAll()
142    {
143      IList<AdminInfo> adminCollection = new List<AdminInfo>();
144      Gateway.SetDefaultDatabase("NBearConnectionString");
145      TAdmin[] tAdminCollection = Gateway.Default.FindArray<TAdmin>(null, TAdmin._.ID.Desc);
146      foreach (TAdmin tAdmin in tAdminCollection)
147      {
148        adminCollection.Add(AdminConvertor.NBearEntityToCommonEntity(tAdmin));
149      }
150      return adminCollection;
151    }
152  }
153}


[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐