翻译的目的一是锻炼 E 文,二是为学些东西,如果这是有任何翻译问题,请通知我一声 ( mailto:[email protected] 或者 http://wonderf.blogone.net/ )
由于本人 E文有限,错误还请包涵。
原文: http://www.15seconds.com/issue/040112.htm
关键字: ORP ObjectSpaces 对象 关系 持久
** .NET ** ** 的对象关系持久化机制 ** ** **
** 第一章 ** ** ** ** 关于一种新的数据访问方式 ** ** **
介绍
在几个星期前, .NET 对象关系持久化( object-relational persistence for .NET )的爱好者还是屈指可数。他们认为,可以用一种专门的数据提供方式从应用程序中消除那些冗长的 ADO.net 代码和减少商业逻辑代码。事实上大多数的 .NET 开发者,希望可以少写些数据访问层( ADO.NET )的代码
如果你参加了 PDC 会议,你可以从许多线索中了解到 Microsoft 的一个新的数据访问策略。在 whidbey 和之后的 visual studio 版本,将会大量增加 ORP (对象关系持久化)功能。
令我惊喜的是有许多人参加了我和 Dave Foderick 主持的 object-relational Birds of a Feather (BoF) 会议。我原先期望会议 大约有 10 几位关注 ORP 的专业人士参与,讨论关于 ORP, 以及目前 .NET OR 工具,聊聊各自的经验。出乎意料的是,有超过 100 位的人士参与了这次讨论。有支持者,反对者,一些感兴趣的人,甚至一些 OR 的工具厂商,气氛很热烈。整个下午, Microsoft 的 ObjectSpaces team 在一个挤满人的房间里演示了 ORP framework 。
对象关系这种能力并不是只用于 ObjectSpaces. 你可以在微软的下个 SQL server 版本 Yukon 中找到很多 OR ( object - relational )痕迹。 Yukon 可以运行基于 clr 的代码,使用 .net 语言编写的存储过程和 clr 类型。业务对象可以通过 ado.net 的参数传递到存储过程,然后被 .net 存储过程代码分解成关系结构,除此之外, Yukon 表的 数据列可以是包含基于 clr 的复杂类型。假设这样的一种情况,一个业务对象作为参数被传递到 Yukon ,这个对象可以持久的作为一个列值被保存到数据库,要比分解成关系结构再存入数据库好的多。
假设在一个应用中,有一个 Person 类用来保存个人的简单信息,包括 id , name , birthday
以下是这个 Person 表 在 sql server 2000 中的 DDL 定义
CREATE TABLE [dbo].[Person] (
[Id] [int] IDENTITY (1, 1) NOT NULL ,
[Name] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[Birthday] [datetime] NULL
) ON [PRIMARY]
而在 Yukon 中你可以这样写:
CREATE TABLE [dbo].[Person] (
[Id] [int] IDENTITY (1, 1) NOT NULL ,
[Person] [Person] NOT NULL
) ON [PRIMARY]
两者主要的不同之处是: Yukon DDL 中含有一个 Person 类型的列,而 Person 是 .NET 对象,显而易见,在 Yukon 中你可以直接定制一个 .net 对象类型的列。
为了使这个column能容纳CLR类型 ,首先这个类型将被编译,然后安装到 sql server。
看一个 person 类的例子:
using System;
using System.Data.Sql;
using System.Data.SqlTypes;
using System.Runtime.Serialization;
namespace ScottBellware.PersonExample
{
///
1<summary>
2
3/// Represents a Person.
4
5/// </summary>
[Serializable]
[SqlUserDefinedTypeAttribute(Format.UserDefined)]
public class Person
{
private int id;
private string name;
private DateTime birthday;
public int Id
{
get{return this.id;}
set{this.id = value;}
}
public string Name
{
get{return this.name;}
set{this.name = value;}
}
public DateTime Birthday
{
get{return this.birthday;}
set{this.birthday = value;}
}
}
}
当这个类编译成 dll 文件后,你可以在 sql server Yukon 中注册它,这是注册 dll 的 T-sql 语句:
CREATE ASSEMBLY PersonExample FROM 'C:\Assemblies\ScottBellware.PersonExample.dll'
这样就在 Yukon 里创建了这个类,本质上是在 Yukon 里为这个类注册了个别名, yukon 会引用这个包含在 dll 里的 clr 类型。在上面的 DDL 表里定义了一个 person 类型的列,所以需要在 Yukon 中创建这个类型
创建的代码如下:
CREATE Type Person
EXTERNAL NAME [PersonExample]:Person
你可以使用带参数的 DML 语句向 Person 表里插入一个 Person 实例
INSERT INTO Person (Person) values (@Person)
如果你有使用 ADO.NET 1.x DataParameter 对象的经验,上面的 DML 语句可能会引起你的好奇。在 ADO .NET 1.0 版本中, DataParameter 对象只可以包装标量值。上面的命令语句显示了在 ADO .NET 2.0 中 SqlParameter class 的改变。你可以通过代码中往数据库传入复杂类型。
往数据库里传入一个定制的类型的所写代码式样类似于通过 ADO .NET 1.x DataParameter objects. 往数据库传入标量值。
在 ADO .NET 2.0 中, SqlParameter 对象实例被通过引用传递, SqlParameter 类新增了一个 UdtTypeName 属性。使用这个属性,来指定 SqlParameter 实例,用来传递复杂类型的 包装参数名字。同样,在 SqlDbType 枚举类型里也增加了 SqlDbType.Udt 类型,来指定复杂类型或用户定义类型的值。
以下的例子示范了 ADO.NET2.0 客户端代码执行一个带有复杂参数的查询。假设已经存在一个名为 connection 的 SqlConnection 对象实例和一个名为 person 的 Person 对象实例,同时数据库连接已经被打开。
// Create a command from the connection object.
SqlCommand insertCommand = conection.CreateCommand();
// Assign the DML to the command command text.
insertCommand.CommandText = NSERT INTO Person (Person) values (@Person)?
// Parameter object to encapsulate the person instance.
SqlParameter parameter = insertCommand.Parameters.Add( Person? SqlDbTypes.Udt );
// Set the type name of the parameter 抯 encapsulated complex type.
** parameter.UdtTypeName = cottBellware.PersonExample.Person? **
// Assign the person instance to the parameter 抯 value.
parameter.Value = person;
// Execute the command.
command.ExecuteNonQuery();
从长远看, Longhorn 将在平台级别带给我们 OR 。 Longhorn 的文件系统基于下一代的 SQL Server 技术,而 ObjectSpaces 将在其中扮演关键的角色,已经成为 Longhorn API 中的基本对象。
你会在微软将要发布 MBF 中看到对象关系持久化机制。 MBF 提供抽象机制来描述业务对象和创建商业应用的业务过程,同时它也可以被 ObjectSpaces 保持持久化。
对象关系持久化在传统的数据访问中使用很少,而在 .NET的数据访问模式和机制中得到应用。 .NET的数据访问命令和结果通过数据访问层的api传递,即使这些是在对象关系持久的架构内。对象关系持久架构提取底层API 与ADO.NET提取底层的本地客户端库使用类似的方法,而通过更高级的抽象,客户端代码变得更清晰,可读。