NHibernate 3.2 Mapping By Code 操纵实例
来源:互联网 发布:鸿雁传书软件下载 编辑:程序博客网 时间:2024/06/05 05:29
繼Linq to SQL、Entity Framework之後,最近又碰了一套ORM就是"NHibernate"
在初步的認識他之後,覺得這套的擴充性與功能方面都十分強大。
當然目前對他的掌握度還沒有很高,因此可能寫不出內容豐富的文章
但這篇要介紹的是 NHibernate 3.2 內建的Mapping By Code,將過去資料庫與類別
對應的xml改為到cs檔裡面撰寫,除了有強型別好處外,也可讓開發人員
更容易設計自己的類別。
本篇利用ASP.NET MVC + NHibernate 3.2 實作
資料庫選用SQLite,並利用Code First在執行時期建立出資料庫
由於網路上目前NHibernate與Mapping By Code的中文文章相對的不多,因此會
著重NHibernate這個部分,並簡單的做出一個CRUD的功能。
首先建立一個新的ASP.NET MVC 2空白專案,並利用NeGet 抓取NHibernate 3.2 版
搜尋NHibernate,並且安裝
安裝好後,開始寫第一個Product類別
Product.cs
01
public
class
Product
02
{
03
public
virtual
int
Id {
get
;
set
; }
04
public
virtual
string
Name {
get
;
set
; }
05
public
virtual
int
Price {
get
;
set
; }
06
public
virtual
int
Quantity {
get
;
set
; }
07
public
virtual
int
CreateUserId {
get
;
set
; }
08
public
virtual
DateTime CreateTime {
get
;
set
; }
09
public
virtual
int
? EditUserId {
get
;
set
; }
10
public
virtual
DateTime? EditTime {
get
;
set
; }
11
}
注意!!所有成員都必須是virtual。
這個實體類別就是我們在程式中所使用的Product類別,我們可以依實際的需要設計這個類別
接著寫Product類跟資料庫要如何對應的ProductMapping類別
ProductMapping.cs
01
using
System;
02
using
NHibernate.Mapping.ByCode.Conformist;
03
using
NHibernate.Mapping.ByCode;
04
05
namespace
NHibernateMappingByCode.Models.Mapping
06
{
07
//繼承ClassMapping<T>
08
public
class
ProductMapping : ClassMapping<Product>
09
{
10
public
ProductMapping()
11
{
12
/* 如果是共用的屬性可以自訂一個父類別去Mapping
13
* 就可以不用每個類別都寫重複的對應
14
*/
15
//主鍵,產生的類型選擇Identity
16
Id(p => p.Id, map => map.Generator(Generators.Identity));
17
Property(p => p.CreateTime, map => map.NotNullable(
true
));
18
Property(p => p.CreateUserId, map => map.NotNullable(
true
));
19
Property(p => p.EditTime);
20
Property(p => p.EditUserId);
21
22
Property(p => p.Name, map => { map.Length(50); map.NotNullable(
true
); });
23
Property(p => p.Price, map => map.NotNullable(
true
));
24
Property(p => p.Quantity, map => map.NotNullable(
true
));
25
}
26
}
27
}
這邊採用的是Conformist Mapping,另外還有一種方式是下面這種Specific Mapper,就不介紹了。
1
var mapper =
new
ModelMapper();
2
mapper.Class<TestClass>(cm =>
3
{
4
cm.Id(p => p.Id, map => map.Generator(Generators.Identity));
5
cm.Property(p => p.Something);
6
});
關於Mapping的設定還有非常多,像一對多、多對一、多對多、Cache等..設定
等研究透徹一點後再慢慢分享出來。
寫完了我們的實體類別跟對應之後,接著就來設定連線
NHibernateUtility.cs
01
using
System;
02
using
System.Collections.Generic;
03
using
System.Linq;
04
using
System.Web;
05
using
NHibernate.Cfg;
06
using
NHibernate;
07
using
NHibernate.Dialect;
08
using
System.Data;
09
using
NHibernate.Cfg.MappingSchema;
10
using
NHibernate.Mapping.ByCode;
11
using
System.Reflection;
12
using
NHibernateMappingByCode.Models.Mapping;
13
14
namespace
NHibernateMappingByCode.Models
15
{
16
public
class
NHibernateUtility
17
{
18
public
static
Configuration Configuration {
get
;
private
set
; }
19
20
public
static
ISessionFactory SessionFactory {
get
;
private
set
; }
21
22
public
void
Initialize()
23
{
24
Configuration = Configure();
25
26
SessionFactory = Configuration.BuildSessionFactory();
27
}
28
29
private
Configuration Configure()
30
{
31
var configuration =
new
Configuration();
32
33
// 資料庫設定
34
// 這裡的東西可以改用xml的方式設定,增加修改的彈性
35
configuration.DataBaseIntegration(c =>
36
{
37
// 資料庫選用 SQLite
38
c.Dialect<SQLiteDialect>();
39
// 取用 .config 中的 "MyTestDB" 連線字串
40
c.ConnectionStringName =
"MyTestDB"
;
41
// Schema 變更時的處置方式
42
c.SchemaAction = SchemaAutoAction.Update;
43
// 交易隔離等級
44
c.IsolationLevel = IsolationLevel.ReadCommitted;
45
});
46
47
// 取得Mapping
48
// 取代舊有的 *.hbm.xml
49
var mapping = GetMappings();
50
51
//加入Mapping
52
configuration.AddMapping(mapping);
53
54
return
configuration;
55
}
56
57
private
HbmMapping GetMappings()
58
{
59
var mapper =
new
ModelMapper();
60
61
//加入Mapping
62
//如果是多個 Type 可用 AddMappings
63
mapper.AddMapping(
typeof
(ProductMapping));
64
65
HbmMapping mapping = mapper.CompileMappingForAllExplicitlyAddedEntities();
66
return
mapping;
67
}
68
}
69
}
Configuration就是以往NHibernate設置在hibernate.cfg.xml的連線設定
當然設定在xml中修改後不需要重新編譯,使用上較方便,但這邊介紹的是另外一種寫法。
由於是Code First,因此在開發時完全不需要考慮到資料庫,這是讓我覺得Code First最
棒的一點,如果需要更換資料庫的話,只需要更改上方的
1
//c.Dialect<SQLiteDialect>();
2
//更換成使用 SQL 2008
3
c.Dialect<MsSql2008Dialect>();
並將連線字串改為SQL 2008資料庫的設定,在Application重啟時,就會在對應的資料庫
中生成Table。
接著在Global.asax.cs中,Application_Start()時加入
1
protected
void
Application_Start()
2
{
3
NHibernateUtility utility =
new
NHibernateUtility();
4
utility.Initialize();
5
6
AreaRegistration.RegisterAllAreas();
7
8
RegisterRoutes(RouteTable.Routes);
9
}
然後運行時就會把Table建出來了。
另外還有一點要注意的是,這邊SchemaActoin設定是Update
也就是Product類別與ProductMapping對應有改變時,就會Update資料庫的Schema
當系統上線後,不妨把這一行拿掉,以免不小心被誰改到了結果資料庫整個亂掉
到這邊為止我們已經有了一張Product Table
為了讓範例完整一點,就寫一個ProductService做出CRUD的功能
(這邊沒有特別去管理Session與實作Repository,因此僅供參考就好)
ProductService.cs
001
using
System;
002
using
System.Collections.Generic;
003
using
System.Linq;
004
using
System.Web;
005
using
NHibernate;
006
using
NHibernate.Linq;
007
008
namespace
NHibernateMappingByCode.Models
009
{
010
public
class
ProductService
011
{
012
public
IEnumerable<Product> GetAll()
013
{
014
IEnumerable<Product> model;
015
using
(var session = NHibernateUtility.SessionFactory.OpenSession())
016
{
017
model = session.Query<Product>().ToList();
018
}
019
return
model;
020
}
021
022
public
Product GetSingle(
int
id)
023
{
024
Product model;
025
using
(var session = NHibernateUtility.SessionFactory.OpenSession())
026
{
027
model = session.Get<Product>(id);
028
}
029
return
model;
030
}
031
032
public
void
Insert(Product model)
033
{
034
model.CreateTime = DateTime.Now;
035
model.CreateUserId = 1;
036
037
//如同時處理好幾張表,可加入交易避免例外發生時產生髒資料
038
using
(var session = NHibernateUtility.SessionFactory.OpenSession())
039
using
(var trans = session.BeginTransaction())
040
{
041
try
042
{
043
session.Save(model);
044
trans.Commit();
045
}
046
catch
(Exception ex)
047
{
048
// Log...
049
trans.Rollback();
050
}
051
}
052
}
053
054
public
void
Update(
int
id, Product model)
055
{
056
var soucre = GetSingle(id);
057
058
if
(soucre !=
null
)
059
{
060
soucre.Name = model.Name;
061
soucre.Price = model.Price;
062
soucre.Quantity = model.Quantity;
063
soucre.EditTime = DateTime.Now;
064
soucre.EditUserId = 1;
065
066
//如同時處理好幾張表,可加入交易避免例外發生時產生髒資料
067
using
(var session = NHibernateUtility.SessionFactory.OpenSession())
068
using
(var trans = session.BeginTransaction())
069
{
070
try
071
{
072
session.SaveOrUpdate(soucre);
073
trans.Commit();
074
}
075
catch
(Exception ex)
076
{
077
// Log...
078
trans.Rollback();
079
}
080
}
081
}
082
}
083
084
public
void
Delete(
int
id)
085
{
086
var model = GetSingle(id);
087
088
if
(model !=
null
)
089
{
090
using
(var session = NHibernateUtility.SessionFactory.OpenSession())
091
using
(var trans = session.BeginTransaction())
092
{
093
try
094
{
095
session.Delete(model);
096
trans.Commit();
097
}
098
catch
(Exception ex)
099
{
100
// Log...
101
trans.Rollback();
102
}
103
}
104
}
105
}
106
}
107
}
HomeController.cs
01
namespace
NHibernateMappingByCode.Controllers
02
{
03
public
class
HomeController : Controller
04
{
05
ProductService _prodcutService;
06
07
public
HomeController()
08
{
09
_prodcutService =
new
ProductService();
10
}
11
12
public
ActionResult Index()
13
{
14
var model = _prodcutService.GetAll();
15
return
View(model);
16
}
17
18
public
ActionResult Insert()
19
{
20
return
View();
21
}
22
23
[HttpPost]
24
public
ActionResult Insert(Product model)
25
{
26
_prodcutService.Insert(model);
27
return
RedirectToAction(
"Index"
);
28
}
29
30
public
ActionResult Update(
int
id)
31
{
32
var model = _prodcutService.GetSingle(id);
33
return
View(model);
34
}
35
36
[HttpPost]
37
public
ActionResult Update(
int
id, Product model)
38
{
39
_prodcutService.Update(id, model);
40
return
RedirectToAction(
"Index"
);
41
}
42
43
public
ActionResult Delete(
int
id)
44
{
45
_prodcutService.Delete(id);
46
return
RedirectToAction(
"Index"
);
47
}
48
}
49
}
- NHibernate 3.2 Mapping By Code 操纵实例
- A003使用NHibernate 3.2实现Repository(ORuM)(三)NHibernate、Mapping、Mapping-By-Code
- A004使用NHibernate 3.2实现Repository(ORuM)(四)NHibernate、Mapping、Mapping-By-Code、AutoMapping
- Nhibernate 映射 FluentApi Mapping by Code
- NHibernate剖析:Mapping篇之Mapping-By-Code(1):概览
- NHibernate实例
- NHibernate Inheritance Mapping 继承映射
- Nhibernate Duplicate class/entity mapping
- NHibernate Inheritance Mapping 继承映射
- NHibernate Step by Step
- NHibernate Step by Step
- NHibernate Step by Step (一) Hello,NHibernate!
- NHibernate Step by Step (一) Hello,NHibernate!
- NHibernate Step by Step (一) Hello,NHibernate!
- NHibernate Step by Step (一) Hello,NHibernate!
- NHibernate Step by Step (一) Hello,NHibernate!
- NHibernate Step by Step (一) Hello,NHibernate!
- NHibernate Step by Step (一) Hello,NHibernate!
- wxpython 键值
- Web开发链接SQL
- MaxOsx 下安装Xdebug
- 数组作为函数参数
- php 获取一个文件中return array() 的值
- NHibernate 3.2 Mapping By Code 操纵实例
- 如何查看一个进程的启动时间
- 用ORACLE的PROFILE限制ORACLE用户
- [深入浅出iOS库]之图形库Core Plot
- 生成随机颜色
- jquery 内置对象
- 贪吃蛇代码(捕捉方向键需要使用wx.EVT_KEY_UP事件)
- 手机停机后你们知道怎么打电话?教你鲜为人知的手机锦囊
- android中service、activity、broadcast的使用