Enterprise Library(企业库)给我们提供的ORM
1 引言
本文的使用的实例数据库为:Northwind
企业库版本:V5.0
下面的例子均在ASP.NET中进行演示。
ORM,Object Relation Mapper,主要是说我们的编程语言,尤其是我们使用面向对象编程语言的时候,都在使用对象,实体,Object,对象之间用属性来维护数据关系。也就是1:n,n:1,1:1,n:n等等。在配合数据库开发的时候,使用的大多是关系型数据库,关系型数据库靠关系Relation来维护数据,表现形式就是二维的数据表。
对象和关系不是一一映射的关系。就好像一张数据库的表,这样一个二维关系,映射为C#中的对象的话,可能是多个对象。还有可能几张表映射为一个对象。很少有一张表映射为一个对象。因为类的设计和数据库表的设计不是一种思路,他们的规范也不尽相同。
这时候就引出了ORM,对象和关系之间的映射。如何更好的映射?都是很多人研究的课题。我也写过一篇文章,讨论过一种实现方法。大多数的方法都是利用列名和属性名来实现映射。
其实在企业库中,至少是在V5.0中就存在这样的映射辅助类,今天就让我们来看看企业库中提供给我们的ORM映射工具。
2 正文
2.1 简单应用
在web.config文件中添加下面的配置
代码
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
<
configSections
>
<
section
name
="dataConfiguration"
type
="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
requirePermission
="true"
/>
</
configSections
>
<
dataConfiguration
defaultDatabase
="sql2005dev"
>
</
dataConfiguration
>
<
connectionStrings
>
<
add
name
="sql2005dev"
connectionString
="server=KB-SHIWENBIN\SQL2005DEV;database=northwind;uid=sa;pwd=123.com"
providerName
="System.Data.SqlClient"
/>
</
connectionStrings
>
在一个页面的后台代码中敲下如下面的代码
代码
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
Database db
=
DatabaseFactory.CreateDatabase ();
IRowMapper
<
Customer
>
mapper
=
MapBuilder
<
Customer
>
.BuildAllProperties () ;
var accessor
=
db.CreateSprocAccessor
<
Customer
>
(
"
GetAllFromCustomers
"
);
var customerData
=
accessor.Execute();
foreach
(var c
in
customerData)
{
Response.Write(c.CompanyName);
Response.Write(
"
</br>
"
);
}
GetAllFromCustomers为存储过程的名称
代码
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
set
ANSI_NULLS
ON
set
QUOTED_IDENTIFIER
ON
go
ALTER
PROCEDURE
[
dbo
]
.
[
GetAllFromCustomers
]
AS
BEGIN
--
SET NOCOUNT ON
SELECT
[
customers
]
.
[
Address
]
AS
'
Address
'
,
[
customers
]
.
[
City
]
AS
'
City
'
,
[
customers
]
.
[
CompanyName
]
AS
'
CompanyName
'
,
[
customers
]
.
[
ContactName
]
AS
'
ContactName
'
,
[
customers
]
.
[
ContactTitle
]
AS
'
ContactTitle
'
,
[
customers
]
.
[
Country
]
AS
'
Country
'
,
[
customers
]
.
[
CustomerID
]
AS
'
CustomerID
'
,
[
customers
]
.
[
Fax
]
AS
'
Fax
'
,
[
customers
]
.
[
Phone
]
AS
'
Phone
'
,
[
customers
]
.
[
PostalCode
]
AS
'
PostalCode
'
,
[
customers
]
.
[
Region
]
AS
'
Region
'
FROM
[
dbo
]
.
[
Customers
]
[
customers
]
SET
NOCOUNT
OFF
END
定义实体类
代码
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
public
class
Customer
{
public
string
CustomerID {
get
;
set
; }
public
string
CompanyName {
get
;
set
; }
public
string
ContactName {
get
;
set
; }
public
string
ContactTitle {
get
;
set
; }
public
string
Address {
get
;
set
; }
public
string
City {
get
;
set
; }
public
string
Region {
get
;
set
; }
public
string
PostalCode {
get
;
set
; }
public
string
Country {
get
;
set
; }
public
string
Phone {
get
;
set
; }
public
string
Fax {
get
;
set
; }
}
这样就可以了,可以看到从数据库读取customer信息,然后映射为实体集合。database的CreateSprocAccessor方法配合存储过程使用,CreateSqlStringAccessor方法配合sql语句使用。
2.2 如何传入参数
其实我们很多时候需要执行的sql语句和存储过程都会有参数传入。这里假设我们需要执行的sql语句是
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
SELECT
*
from
Customers
WHERE
CompanyName
like
@p1
and
contactname
like
@p2
有两个参数@p1,@p2
首先我们需要自定义一个参数映射类
代码
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
public
class
ExampleParameterMapper : IParameterMapper
{
public
void
AssignParameters(DbCommand command,
object
[] parameterValues)
{
DbParameter parameter
=
command.CreateParameter();
parameter.ParameterName
=
"
@p1
"
;
parameter.Value
=
parameterValues[
0
];
command.Parameters.Add(parameter);
parameter
=
command.CreateParameter();
parameter.ParameterName
=
"
@p2
"
;
parameter.Value
=
parameterValues[
1
];
command.Parameters.Add(parameter);
}
}
然后我们将c#的代码修改一下,在创建访问器的时候指定一下参数映射实例,在执行的时候传入参数的值。
代码
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
Database db
=
DatabaseFactory.CreateDatabase ();
string
query
=
"
SELECT * from Customers WHERE CompanyName like @p1 and contactname like @p2
"
;
IParameterMapper mapper
=
new
Classes.ExampleParameterMapper ();
var accessor
=
db.CreateSqlStringAccessor
<
Customer
>
(query, mapper);
var customerData
=
accessor.Execute(
new
string
[] {
"
%stock%
"
,
"
%s%
"
});
foreach
(var c
in
customerData)
{
Response.Write(c.CompanyName);
Response.Write(
"
</br>
"
);
}
这样就可以了。
2.3 定义输出结果的映射关系
2.3.1 使用默认的输出映射方法
在你创建SprocAccessor和SqlStringAccessor类的时候,或者是使用database的CreateSqlStringAccessor和CreateSpocAccessor的时候,不需要你提供输出映射的方法。默认的情况下,使用数据库结果集中的列的名称和类的属性的名称进行映射,如果一个属性没有找到匹配的列,就会抛出InvalidOperationException的异常提示。如果结果集中的列,没有类属性对应的话,就不做任何处理,忽略这个列。另外,默认的映射方法不支持集合属性的映射。
2.3.2 自定义输出映射方法
有的时候我们在映射的时候,有一些列需要特殊的处理。