ORM in .NET 3.5

出处:http://i.aspx1.com/showtopic-710.htm

作者:Luke Stratman
原文链接:http://dotnetslackers.com/articles/net/ORMInNET35.aspx
Introduction    
    ORM,对象-关系映射,在现代面向对象编程语言中,其中实现起来比较棘手的事。它包括摒弃传统的数据存储机制:这里没有(或很少)专门的、预编译的代码,涉及读(写)对象从(到)数据库或其它后备存储中。作为替代,涉及访问后备存储的逻辑在运行时被决定,通过运用一系列反射和特性机制修饰正在考虑的业务对象。许多已经建立的工程和框架试图提出这个观念并取得了多方面的成功。这篇文章覆盖了:概括介绍ORM理念,一种.NET3.5携带的途径,及其和其他框架的比较。

In the beginning...

 

在.NET3.5之前,当你需要把你的业务对象从数据库读取或写入时,你有以下几个选择:

 

1.
自己动手 – 这意味着你不需要任何框架,不需要自动生成任何代码。数据库结构和.NET类都是手工建立的,数据访问层也是如此。虽然这将会提供最终的执行,但是当对象或数据库结构改变时,它将是乏味的(包括复制大量重复代码),易出错的,难以维护的。

 

2.
自动生成类和数据访问层 – 这就是自动生成工具CodeSmith和MyGeneration到来的缘由:你在你的数据库中指明它们,它将自动生成.NET类和数据访问层。看看第一条选择,这不是真正的ORM:你仍然有预编译代码负责访问数据库用来读取或写入对象的数据。不过,它的自动生成代码机制在这方面做出了正确的一步,排除了当创建类和数据访问层时易出错的人为因素。

 

3.
运用真正的ORM框架 – 在先前的.NET框架版本中,这里有一些知名的ORM框架可获取,包括NHibernate和Gentle.NET。就如事先提到的,ORM移除了专注于数据存储的代码和在运行时检查一个对象来决定从数据库读取或写入这个对象需要做哪些工作。特性用来修饰类和类的属性,用以给出标识类和数据库的映射。一个操作的真实SQL是基于这些特性动态生成的。经常有一个代码自动生成组件在这些框架中用来从数据库结构中生成业务对象类,但是关注于数据访问的代码没有生成。


Major Malfunctions(缺点) with ORM

所有这些动态的,运行时的SQL生成机制听起来不错,是么?并非如此:ORM有一些严重的缺点。第一个就是性能问题,因为在任何时候你把反射引入并开始动态生成SQL,你会遭遇减速。ORM永远不会和自己手动处理一样快:没有替代品可以替代“手拧”存储过程和预编译所有数据访问逻辑。另一个缺点是ORM对极度复杂的数据库处理的不好。当设计很多约束和关系跨越多个表的复杂数据库时,这经常有必要包括中间表去把各种实体关联起来,这从RDBMS的立场看似乎不错,但是在一个面向对象环境中看起来有点牵强。这也将导致难以理解自动生成的类。紧记,RDBMS和面向对象环境是根本不同的,它们各自拥有一套设计和性能考量。在一个环境中动作良好并不意味在另一个环境中亦如此。话虽如此,ORM以可维护、干净的、易懂的代码的方式提供正确的使用总是比较牵强的。

LINQ, DataContexts, and general ORM in .NET 3.5

 


目前为止,你对ORM已经有了整体的了解和它潜在的陷阱,让我们探讨一下Microsoft在.NET3.5中是如何接近这个观念的。它提出了一个不同的途径去挑战ORM,它并不把焦点集中在对象模型、关系模型,它提供给我们一套全新的思路去访问和查询数据,这并不局限于关系数据。通过这个途径,.NET3.5的ORM能力发展成了这个新的数据访问架构,几乎如同副作用一般,取代了原来的焦点。他们是怎样做到的?LINQ。它代表集成查询语言,Microsoft想把它变成在.NET框架中筛选数据的途径。它的结构与我们平时写SQL语句很类似,它非常简单,并且拥有对强类型面向对象语言强有力的SQL查询语法。实际的反对者,然而,是它不仅仅局限于关系数据:只要实现了IEnumerable和IQueryable接口,就能使用LINQ。这里有一个例子,你可以从中知道它的能力:

List<string> elements = new List<string>(){"Iridium","Einsteinium","Polonium"};IEnumerable<string> results = from element in elementswhere element.Contains("n")select element;
这只是一个简单的从elements中查询包含字母”n”的普通字符串例表实例。然而在之前你不得不命令式地完成这项功能,也就是你将不得不写代码迭代集合来驱动查询,现在你可以直接地完成相同的功能。基本上,你陈述你要做什么来替代如何去做。当用这种语法,这种途径固有地不太会出错。它同样也支持提及的智能感知,所以当你从事于LINQ编程时,你一点也不会在Visual Studio中损失轻松使用的特征。

 

那么,我们来看看LINQ是如何适合ORM的。第一,这里有一个代码生成组件:LINQ并没有避开它由于你不得不定义映射数据库中的关系数据为类似于面向对象世界的类。为了做到这一点,Microsoft提供一个叫做SQLMetal的工具。为了使用它,仅仅打开Visual Studio命令行提示(Start->Programs->Visual Studio 9.0->Visual Studio Tools->Visual Studio Codename Orcas Command Prompt),然后打上sqlmetal来看看它的选项。它非常简单:你所需要做的是指明它的数据库,告诉代码文件的名称和(或)你想要生成的DBML文件。我创建了一个简单的名为LinqTest的数据库,它包含两张表:Person和PersonAddress。PersonAddress有一名为personId的列,它是一个外部键,用来关联Person表中相匹配的列。所以,我运用如下命令产生ORM类:

 

sqlmetal /database:LinqTest /language:csharp /code:LinqTest.cs

 


从这个过程得到的代码结果中包含两套类:DataContext类和一系列与数据库中表相符的对象类。对象类非常简单:它们反映出数据库中的表,其中的属性代表每个列。每个类和其属性都被特性修饰,来描述和数据库之间的映射,这和其他ORM框架类似。一个很好的提高是我并没有在任何地方发现,除非每个对象类自动执行INotifyPropertyChanging和INotifyPropertyChanged,这意味着它们暴露了当一个属性的值改变时允许外界类去响应的事件。为了促进这一点,要点是每个属性包装到OnPropertyChanging()和OnPropertyChnaged回调方法,依次触发事件处理函数,如果它们设置了。另一个漂亮的特征是这样一个事实,所有由SQLMetal产生的类都是部分类,它们仅仅实现必要的核心功能。这意味着你可以通过分离代码文件自由的添加类功能,不需要更新自动生成的输出。DataContext类提供链接到包含将用于移植到对象类的数据的后备存储的服务(在这个例子里是数据库)。你通过一个连接字符串或一个初始化了的数据连接对象来得到它的构造器,依次,它暴露一系列泛型属性Table<>,其中每个都代表数据库中的一张表。这些Table<>属性是真正给予LINQ力量的:Table<>类是完全支持LINQ的,它负责于扮演LINQ与数据库间的接口,将LINQ语法翻译成必要的SQL语句,从而从数据库中检索你的数据。同样地对于先前的例子,让我们来看看另一个使用Table<>属性的LINQ查询:

 

LinqTest linqTest = new LinqTest("Data Source=DDVPC01""SQLEXPRESS;Initial Catalog=LinqTest;Integrated Security=True");IEnumerable<Person> results = from person in linqTest.Personwhere person.FirstName.StartsWith("L")select person;

 


所有这些讲述了ORM实现是如何地困难,鉴于在.NET3.5中其他的看起来有点虎头蛇尾:它对于有SQL经验的非常容易懂,它完全集成于语言及开发环境,而且它令人惊讶的快。想添加一个新Person信息到数据库?没问题:

 

linqTest.Person.Add(new Person(){FirstName = "Mike",LastName = "Smith"});linqTest.SubmitChanges();

 

只要你调用必要的Table<>属性的Add()方法,做完这步之后,调用DataContext类的SubmitChanges()方法。

 

Wrapping it up 总结

我希望这篇文章能给你一些好的建议对于在.NET3.5中处理ORM。这并不是解决所有挑战数据访问的银弹,但就如任何一个优秀的程序员所知,这从来就没有。当数据库结构很复杂并且性能至关重要时,这里就没有办法替代手工写代码,调整.NET数据访问代码和SQL逻辑。但是,至于明确的结构和.NET中一般的数据过滤,LINQ表现为一种新的,诡秘的ORM实现。


posted on 2008-05-03 00:37 nicholas.sun
本文来自: ASP.NET学习门户(http://www.aspx1.com) 详细出处参考:http://i.aspx1.com/showtopic-710.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值