服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - 在C#项目中如何使用NHibernate详解

在C#项目中如何使用NHibernate详解

2022-02-22 13:32灵动生活 C#

NHibernate的设计思想和Hibernate的设计思想基本相同,都是为了避免频繁的编写sql脚本,使用面向对象的方式使用hql语句进行查询。下面这篇文章主要给大家介绍了关于在C#项目中如何使用NHibernate的相关资料,需要的朋友可以参考借鉴

前言

现代化大型项目通常使用独立的数据库来存储数据,其中以采用关系型数据库居多。用于开发项目的高级语言(c#、java等)是面向对象的,而关系型数据库是基于关系的,两者之间的沟通需要一种转换,也就是对象/关系数据库映射(object/relational mapping,简称orm)。

c#可用以解决对象/关系数据库映射的工具有多种,常见的有ef (entity framework)、nhibernate、ibatis等,各自的优缺点及适用场景在此不做讨论,本文只对如何使用nhibernate做个总结。

nhibernate是一个面向.net环境的对象/关系数据库映射工具。

1. 创建项目文件

在visual studio开发工具里创建需要的项目结构。

2. 添加对nhibernate的引用

当下载并解压nhibernate安装包后,电脑上就会创建一些目录,包括“required_bins”,要把 required_bins目录下的dll引用到项目里来,它们是nhibernate使用的核心组件。

nhibernate.dll(基础类库,与数据库直接打交道,位于数据访问层)

iesi.collections(基础类库辅助类库,位于数据访问层)

antlr3.runtime(基础类库辅助类库,位于数据访问层)

nhibernate.bytecode.spring.dll(proxy factory类库,用于打开/关闭nhibernate session,位于数据访问层工具类库)

 在C#项目中如何使用NHibernate详解

 图1 添加对nhibernate的引用

3. 配置nhibernate

文件:hibernate.cfg.xml,位于站点根目录。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
 <session-factory>
 <property name="connection.driver_class">nhibernate.driver.sqlclientdriver</property>
 <property name="connection.connection_string">
 data source=120.120.200.200;initial catalog=mamall;persist security info=true;user id=mamall;password=mima123;connection reset=false;connection lifetime=50;min pool size=1;max pool size=500
 </property>
 <property name="adonet.batch_size">10</property>
 <property name="show_sql">true</property>
 <property name="dialect">nhibernate.dialect.mssql2005dialect</property>
 <property name="command_timeout">10</property>
 <property name="query.substitutions">true 1, false 0, yes 'y', no 'n'</property>
 <property name="proxyfactory.factory_class"> nhibernate.bytecode.spring.proxyfactoryfactory,nhibernate.bytecode.spring</property>
 <property name="connection.release_mode">on_close</property>
 <mapping assembly="fuli.entity"/>
 </session-factory>
</hibernate-configuration>

4. 编写nhibernatehelper辅助类

文件:nhibernatehelper.cs

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using system;
using fuli.tool.log;
using nhibernate;
using nhibernate.cfg;
namespace fuli.dal.common
{
 public class nhibernatehelper
 {
 private static isessionfactory _sessionfactory;
 private static isessionfactory sessionfactory
 {
  get
  {
  if (_sessionfactory == null)
  {
   var configuration = new configuration();
   configuration.configure();
   _sessionfactory = configuration.buildsessionfactory();
  }
  return _sessionfactory;
  }
 }
 
 public static isession opensession()
 {
  try
  {
  return sessionfactory.opensession();
  }
  catch (exception ex)
  {
  loghelper.getinstance().writemessage("打开数据库失败,错误:" + ex.tostring());
  return null;
  }
 }
 }
}

5. 创建数据模型

nhibernate允许直接使用plain old clr objects (pocos),而不用通过存储过程来直接和数据库交互。使用pocos的一个优势在于不用绑定特定的持久化层。相比较而言,有些orm解决方案需要特殊属性,或者是基于模型对象,这些对象又是从特定的基类中继承而来的。

在nhibernate中不用特殊的修饰就可以让对象和持久化层交互。要注意的是所有需要持久化的属性必须是虚拟的,并且要开启延迟加载,所有数据模型类中的公共方法必须是虚拟的,哪怕它们并没有包含到映射文件中。

通常来讲,最好把所有的属性都设置为虚拟的。

可以借助mygeneration自动代码工具从数据表生成数据模型和对应的映射文件。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
using system;
using system.collections.generic;
 
namespace fuli.entity.domain
{
 /// <summary>
 /// 共享编码表(字典表)
 /// </summary>
 [serializable]
 public class sharedcode
 {
 #region 构造方法
 
 public sharedcode()
 {
  m_id = 0;
  m_category = string.empty;
  m_text = string.empty;
  m_value = string.empty;
  m_isdefault = false;
  m_description = string.empty;
  m_parentid = 0;
  m_sortorder = 0;
 }
 
 #endregion 构造方法
 
 #region 私有变量
 
 private long m_id;
 private string m_category;
 private string m_text;
 private string m_value;
 private bool m_isdefault;
 private string m_description;
 private long m_parentid;
 private short m_sortorder;
 
 #endregion 私有变量
 
 #region 公有属性
 
 ///<summary>
 /// 主键id
 ///</summary>
 public virtual long id
 {
  get { return m_id; }
  set { m_id = value; }
 }
 
 ///<summary>
 /// 分类
 ///</summary>
 public virtual string category
 {
  get { return m_category; }
  set { m_category = value; }
 }
 
 ///<summary>
 /// 文本
 ///</summary>
 public virtual string text
 {
  get { return m_text; }
  set { m_text = value; }
 }
 
 ///<summary>
 /// 编码值
 ///</summary>
 public virtual string value
 {
  get { return m_value; }
  set { m_value = value; }
 }
 
 ///<summary>
 /// 是否是同类里默认
 ///</summary>
 public virtual bool isdefault
 {
  get { return m_isdefault; }
  set { m_isdefault = value; }
 }
 
 ///<summary>
 /// 描述
 ///</summary>
 public virtual string description
 {
  get { return m_description; }
  set { m_description = value; }
 }
 
 ///<summary>
 /// 父级id(如果有)
 ///</summary>
 public virtual long parentid
 {
  get { return m_parentid; }
  set { m_parentid = value; }
 }
 
 ///<summary>
 /// 排列次序
 ///</summary>
 public virtual short sortorder
 {
  get { return m_sortorder; }
  set { m_sortorder = value; }
 }
 
 #endregion 公有属性
 
 #region 扩展属性
 
 #endregion 扩展属性
 
 #region rewrite equals and hashcode
 
 /// <summary>
 ///
 /// </summary>
 public override bool equals(object obj)
 {
  if(this == obj) return true;
  if((obj == null) || (obj.gettype() != gettype())) return false;
  sharedcode castobj = (sharedcode)obj;
  return (castobj != null) && (m_id == castobj.id);
 }
 
 /// <summary>
 /// 用唯一值实现gethashcode
 /// </summary>
 public override int gethashcode()
 {
  int hash = 57;
  hash = 27 * hash * m_id.gethashcode();
  return hash;
 }
 
 #endregion rewrite equals and hashcode
 }
}

6. 创建nhibernate映射文件

nhibernate使用xml映射文件来映射poco到数据库对象。虽然在很多案例中这可能是一对一关系,但这并不是必定的。

文件:sharedcode.hbm.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
 <class name="fuli.entity.domain.sharedcode, fuli.entity" table="sharedcode">
  <id name="id" column="id" type="int64" unsaved-value="0">
   <generator class="native"/>
  </id>
  <property name="category" type="string" column="category"/>
  <property name="text" type="string" column="text"/>
  <property name="value" type="string" column="value"/>
  <property name="isdefault" type="boolean" column="isdefault"/>
  <property name="description" type="string" column="description"/>
  <property name="parentid" type="int64" column="parentid"/>
  <property name="sortorder" type="int16" column="sortorder"/>
 </class>
</hibernate-mapping>

在hibernate-maping标签中,同时引用类集(pocos)所属的程序集命名空间。

  • class元素表示到单个poco的映射。name表示上面的程序集和命名空间中的类名,table属性告诉nhibernate数据库中的哪个表或者视图将被映射。
  • id元素告诉nhibernate哪个数据库的字段和对应的对象作为一个唯一键来使用。在本例中,我们使用id这个字段。
  • generator元素告诉nhibernate怎样给新实体来创建唯一id。
  • property标签是见得最多的标签。它简单地映射一个到数据表或者视图中对应字段的映射。

一旦xml文件创建好了,需要更改xml的生成方式确保它被设置为嵌入式资源,否则nhibernate不会读取这个xml文件,那么映射就不会生效了。

 在C#项目中如何使用NHibernate详解

图2 映射文件必须是嵌入的资源

7. 使用 nhibernate连接数据库

文件:commonrepository

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
namespace fuli.dal.sqlserverimpl
{
 public class commonrepository : icommonrepository
 {
  #region 新增
  /// <summary>
  /// 新增实体表
  /// </summary>
  /// <param name="obj"></param>
  /// <returns></returns>
  public long addnewentity<t>(object obj, string tablename) where t : new()
  {
   long id = 0;
   try
   {
    using (isession session = nhibernatehelper.opensession())
    {
     id = long.parse(session.save((t)obj).tostring());
     session.flush();
    }
   }
   catch (exception ex)
   {
    loghelper.getinstance().writemessage(tablename + operationtype.comma + ex.tostring());
   }
   return id;
  }
 
  /// <summary>
  /// 新增实体表
  /// </summary>
  /// <param name="entity"></param>
  /// <returns></returns>
  public treturn addnewentity<tentity, treturn>(object entity, string tablename) where tentity : new()
  {
   treturn returnvalue = default(treturn);
   try
   {
    using (isession session = nhibernatehelper.opensession())
    {
     object returnobject = session.save(entity);
     if (returnobject != null)
     {
      returnvalue = (treturn)convert.changetype(returnobject, typeof(treturn));
     }
     session.flush();
    }
   }
   catch (exception ex)
   {
    loghelper.getinstance().writemessage(tablename + operationtype.comma + ex.tostring());
   }
   return returnvalue;
  }
  #endregion 新增
 }
}

对于不同的实体,可以一对一地写一个<entity>repository,专注负责相对应的实体操作。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

原文链接:http://www.cnblogs.com/ywqu/p/8664360.html

延伸 · 阅读

精彩推荐
  • C#C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    这篇文章主要介绍了C#设计模式之Strategy策略模式解决007大破密码危机问题,简单描述了策略模式的定义并结合加密解密算法实例分析了C#策略模式的具体使用...

    GhostRider10972022-01-21
  • C#SQLite在C#中的安装与操作技巧

    SQLite在C#中的安装与操作技巧

    SQLite,是一款轻型的数据库,用于本地的数据储存。其优点有很多,下面通过本文给大家介绍SQLite在C#中的安装与操作技巧,感兴趣的的朋友参考下吧...

    蓝曈魅11162022-01-20
  • C#如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    这篇文章主要给大家介绍了关于如何使用C#将Tensorflow训练的.pb文件用在生产环境的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴...

    bbird201811792022-03-05
  • C#深入理解C#的数组

    深入理解C#的数组

    本篇文章主要介绍了C#的数组,数组是一种数据结构,详细的介绍了数组的声明和访问等,有兴趣的可以了解一下。...

    佳园9492021-12-10
  • C#VS2012 程序打包部署图文详解

    VS2012 程序打包部署图文详解

    VS2012虽然没有集成打包工具,但它为我们提供了下载的端口,需要我们手动安装一个插件InstallShield。网上有很多第三方的打包工具,但为什么偏要使用微软...

    张信秀7712021-12-15
  • C#利用C#实现网络爬虫

    利用C#实现网络爬虫

    这篇文章主要介绍了利用C#实现网络爬虫,完整的介绍了C#实现网络爬虫详细过程,感兴趣的小伙伴们可以参考一下...

    C#教程网11852021-11-16
  • C#C#微信公众号与订阅号接口开发示例代码

    C#微信公众号与订阅号接口开发示例代码

    这篇文章主要介绍了C#微信公众号与订阅号接口开发示例代码,结合实例形式简单分析了C#针对微信接口的调用与处理技巧,需要的朋友可以参考下...

    smartsmile20127762021-11-25
  • C#三十分钟快速掌握C# 6.0知识点

    三十分钟快速掌握C# 6.0知识点

    这篇文章主要介绍了C# 6.0的相关知识点,文中介绍的非常详细,通过这篇文字可以让大家在三十分钟内快速的掌握C# 6.0,需要的朋友可以参考借鉴,下面来...

    雨夜潇湘8272021-12-28