基于.NET平台的分层架构实战(九)——数据访问层的第三种实现:基于NBear框架的ORM实现
前面的文章讨论了使用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>节点下增加如下项:
<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}
基于.NET平台的分层架构实战(九)——数据访问层的第三种实现:基于NBear框架的ORM实现相关推荐
- 基于.NET平台的分层架构实战(二)——需求分析与数据库设计
基于.NET平台的分层架构实战(五)--接口的设计与实现 · 基于.NET平台的分层架构实战(四)--实体类的设计与实现 · 基于.NET平台的分层架构实战(三)--架构概要设计 · 基于.NET平台 ...
- 基于.NET平台的分层架构实战(一)——综述
通过浏览博客园的文章发现,很多朋友对分层架构特别感兴趣,刚好我刚做完的毕业设计就是专门研究.NET平台上分层架构的(题目叫"基于.NET平台的分层架构与设计模式应用研究").通过做 ...
- 一起谈.NET技术,发布NGuestBook(一个基于.NET平台的分层架构留言本小系统)
发布NGuestBook的动机说明 大约在半年前,我在博客上发表了一个系列文章:<基于.NET平台的分层架构实战>.当时在讲解过程中用到了一个叫NGuestBook的案例,在那以 ...
- 发布NGuestBook(一个基于.NET平台的分层架构留言本小系统)
发布NGuestBook的动机说明 大约在半年前,我在博客上发表了一个系列文章:<基于.NET平台的分层架构实战>.当时在讲解过程中用到了一个叫NGuestBook的案例,在那以后,有很多 ...
- 项目架构开发:数据访问层之Cache
数据访问层简单介绍 数据访问层,提供整个项目的数据访问与持久化功能.在分层系统中所有有关数据访问.检索.持久化的任务,最终都将在这一层完成. 来看一个比较经典的数据访问层结构图 大概可以看出如下信息 ...
- 实战 .Net 数据访问层 - 23
u 使用现成的框架 Ø 首选当然是.NET Framework即将正式推出的ObjectSpaces! Ø 如果希望Total Solution,Borland ...
- 实战 .Net 数据访问层 - 19
6. ASPECT AOP(Aspect Oriented Programming)可能是最近几年被挖掘出 来的最具震撼力的技术之一,作者并不打算在此花什么篇幅介绍它(网上资料已多如牛 ...
- 分层:数据访问层、业务逻辑层、视图层
分层:开发模式 数据访问层 业务逻辑层:调用数据访问层 视图层:调用业务逻辑层 数据库表 1.创建项目 2.创建包: com.zking.util com.zking. ...
- 艾伟:基于.NET平台的Windows编程实战(四)—— 数据库操作类的编写
本系列文章导航 基于.NET平台的Windows编程实战(一)--前言 基于.NET平台的Windows编程实战(二)-- 需求分析与数据库设计 基于.NET平台的Windows编程实战(四)-- 数 ...
- 微软账号登陆不上_企业信息化面临的问题,看看解决方案,基于微软平台的IT架构...
哈喽,今日头条的小伙伴们大家好,我是你们的好朋友IT咨询顾问.小编曾经就工作过程中接触的企业IT环境存在的问题,陆陆续续搜集过一些案例,当时做的笔记是零散的,现在为了方便小伙伴们阅读,整理了一下笔记并 ...
最新文章
- CF587F Duff is Mad
- 告警系统邮件引擎、运行告警系统
- SpringBoot之web开发
- 1031 Hello World for U (20 分)【难度: 一般 / 知识点: 找规律】
- hadoop常见错误即解决方法
- Think in AngularJS :对比 jQuery 和 AngularJS 的不同思维模式
- django 热启动_传统的Web框架如何部署在Serverless架构上(以Flask为例)
- python异常捕获_Python 异常的捕获、异常的传递与主动抛出异常操作示例
- python把英语句子成分字母_英语句子成分分析(最完整版)
- oracle拆分分区语法详解大全_Oracle分区表详解
- java使用poi导出word并且带图片
- 前端开发:遇到提示Invalid prop:type check failed for prop “modelValue“. Expected Number…的解决方法
- ESP32开发路程蓝牙篇——BLE(GATT),修改设备名称,添加characteristic,发送数据,接收数据
- 键盘录入一个字符串,统计该字符串中的大写字母、小写字母、数字字符和其他字符分别有多少个 例如,键盘录入abcABCD12345!@#$%,输出结果为:小写字母有3个,大写字母有4个,数字字符有5个,
- 用python 打印等腰三角形
- 黑苹果 10G 网卡(intel Aquantia)解决方案及big sur 11.x 下驱动方式
- CentOS 6.4 搭建 Java 开发环境详解
- 一、ECharts(各种统计图)
- PCB这个工艺,免费了!
- 计算机网络(期末详细总结)
热门文章
- php session fixation,session fixation攻击
- Python利用re正则表达式抓取豆瓣电影Top250排行榜
- mysql mtq_mysql实现远程登录
- 征信报告 加密文档_如何给PDF文档加密?PDF文档加密的方法
- linux 实现不同网段网络互通
- Excel VBA单元格数据自增1
- java启动后台进程_windows下java -jar 后台运行以及杀死后台进程的操作
- 关于查看nginx的访问量的部分总结
- 在CAD软件中如何批量打印黑白CAD图纸
- 多个excel工作簿合并_Microsoft Excel如何快速合并多个工作簿至一个工作簿中?