Answers:
LINQ to SQL强制您使用每类表模式。使用此模式的好处在于,它实现起来快速简便,并且只需花费很少的精力就可以在现有数据库结构的基础上运行域。对于简单的应用程序,这是完全可以接受的(并且有时甚至更可取),但是对于更复杂的应用程序,开发人员通常会建议改用域驱动的设计模式(这是NHibernate所促进的)。
每类表模式的问题在于数据库结构直接影响您的域设计。例如,假设您有一个“客户”表,其中包含以下列来保存客户的主要地址信息:
现在,假设您也要为客户的邮寄地址添加列,以便在“客户”表中添加以下列:
使用LINQ to SQL,您域中的Customer对象现在将具有这八个列中每个列的属性。但是,如果您遵循域驱动的设计模式,则可能已经创建了一个Address类,并且让Customer类拥有两个Address属性,一个属性用于邮件地址,另一个属性用于其当前地址。
这是一个简单的示例,但它演示了“按表创建表”模式如何导致有些臭味的域。最后,取决于您。同样,对于仅需要基本CRUD(创建,读取,更新,删除)功能的简单应用程序而言,LINQ to SQL由于其简单性而非常理想。但是我个人喜欢使用NHibernate,因为它可以简化域。
编辑:@lomaxx-是的,我使用的示例过于简单,可以进行优化以与LINQ to SQL一起很好地工作。我想让它尽可能地基本,以使观点正确。关键在于,尽管在某些情况下,让数据库结构确定域结构是一个坏主意,或者至少会导致次优OO设计。
迄今为止遗漏了两点:
LINQ to SQL不适用于Oracle或SqlServer以外的任何数据库。 但是,第三方确实为Oracle提供了更好的支持,例如devArt的dotConnect,DbLinq,Mindscape的LightSpeed和ALinq。(我对此没有任何个人经验)
Linq to NHibernate使您可以将Linq与Nhiberate一起使用,因此它可以消除不使用的原因。
而且,新的Nhibernate流畅接口似乎使配置Nhibernate的映射变得不那么麻烦。(消除了Nhibernate的痛苦之一)
更新资料
Linq to Nhiberate在现在处于Alpha的 Nhiberate v3中更好。看来Nhiberate v3可能会在今年年底推出。
从.net 4开始的实体框架工作也开始看起来像是一个真正的选择。
@Kevin:我认为您演示的示例的问题在于您使用的数据库设计不佳。我以为您会创建一个客户表和一个地址表并对其进行规范化。如果这样做,您可以针对您所建议的方案使用Linq To SQL。Scott Guthrie有大量有关使用Linq To SQL的文章,我强烈建议您检查一下。
我认为您不能说Linq和NHibernate互为补充,因为这暗示着它们可以一起使用,尽管这是可能的,但您最好选择一个并坚持下去。
NHibernate允许您以高度灵活的方式将数据库表映射到域对象。它还允许您使用HBL查询数据库。
Linq to SQL还允许您将域对象映射到数据库,但是它使用Linq查询语法来查询数据库
此处的主要区别在于,编译器会在编译时检查 Linq查询语法,以确保您的查询有效。
linq需要注意的一点是,它仅在.net 3.x中可用,并且仅在VS2008中受支持。NHibernate在2.0和3.x以及VS2005中可用。
NHibernate需要注意的一点是,它不会生成您的域对象,也不会生成映射文件。您需要手动执行此操作。Linq可以
自动为您执行此操作。
Fluent NHibernate可以基于简单约定生成映射文件。无需编写XML且具有强类型。
我最近参与了一个项目,出于性能原因,我们需要从Linq更改为SQL到NHibernate。特别是L2S实现对象的方法似乎比NHibernate的同上慢,并且变更管理也很慢。对于不需要的特定场景,可能很难关闭变更管理。
如果要使用与DataContext断开连接的实体-例如在WCF场景中-您可能会遇到很多麻烦,需要将它们再次连接到DataContext来更新更改。NHibernate对此没有任何问题。
我会从L2S遗漏的东西主要是代码生成,该代码生成使实体两端的关系保持最新。但是我想NHibernate也有一些工具可以做到这一点...
.ObjectTrackingEnabled = false
这样您DataContext
就可以解决变更跟踪问题。只要您采用工作单元模式并且不打算进行DDD,Linq-to-SQL确实可以提供。
对于LINQ,我假设您是指LINQ to SQL,因为LINQ本身没有与之关联的数据库。它只是一种查询语言,带有大量语法糖,使其看起来像SQL。
在最基本的基本示例中,NHibernate和LINQ to SQL似乎都在解决相同的问题。一旦获得通过,您很快就会意识到NHibernate支持许多功能,这些功能使您可以创建真正丰富的域模型。还有一个LINQ to NHibernate项目,该项目使您可以使用LINQ来查询NHibernate,其方式与使用LINQ to SQL的方式几乎相同。
首先让我们分开两个不同的方面:数据库建模关注数据,而对象建模关注实体和关系。
Linq-to-SQL的优点是可以从数据库架构中快速生成类,以便可以将它们用作活动记录对象(请参阅活动记录设计模式定义)。
NHibernate的优点是可以在对象建模和数据库建模之间提供灵活性。可以对数据库进行建模,以在考虑性能的情况下最好地反映您的数据。虽然您的对象建模将使用诸如域驱动设计之类的方法来最好地反映业务规则的元素。(请参阅彭凯文的评论)
对于建模和/或命名约定不佳的旧数据库,Linq-to-SQL会将这种不需要的结构和名称反映给您的类。但是,NHibernate可以用数据映射器隐藏这种混乱情况。
在数据库命名良好且复杂度较低的未开发项目中,Linq-to-SQL可能是不错的选择。
但是,您可以将Fluent NHibernate与自动映射一起使用,以实现相同的目的,并按照惯例进行映射。在这种情况下,您不必担心任何带有XML或C#的数据映射器,并让NHibernate根据您可以自定义的约定从您的实体生成数据库架构。
另一方面,Linq-to-SQL的学习曲线比NHibernate小。
或者,您可以使用Castle ActiveRecords项目。我已经使用了很短的时间来为遗留项目增加一些新代码。它使用NHibernate并在活动记录模式上工作(给定我知道的名字,这令人惊讶)。我还没有尝试过,但是我认为一旦您使用了它,如果您觉得需要直接获得NHibernate支持的话,那么对您的部分或全部项目这样做就不会太多了。
正如您为“未使用任何一种工具的人”所写,LINQ to SQL易于使用,因此任何人都可以轻松使用它。它还支持过程,这在大多数情况下都非常有用。假设您要从一个以上的表中获取数据,然后编写一个过程并将该过程拖到设计器中,它将为您创建所有内容,假设您的过程名称为“ CUSTOMER_ORDER_LINEITEM”,它将从这三个表中获取记录,然后编写
MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();
您也可以在foreach循环中使用记录对象,NHibernate不支持