架构设计DAL层

4
我正在设计一个中等规模的Web应用程序,对于我的数据访问层(DAL),我有三个选项:
1) 传统的基于存储过程的架构(使用Codesmith的NTiers模板);
2) LINQ To SQL(或Codesmith的PLINQO模板);
3) LINQ To Entity。
由上述内容可知,LINQ to Entity不适用于我们,因为我们需要快速启动应用程序,并且我们没有足够的技能集来使用它。此外,团队从未使用过任何OR/M工具,学习曲线会很陡峭(这是我在某个地方读到的)。
我更喜欢使用LINQ to SQL(但唯一的担心是微软将不再支持或增强LINQ to SQL),从我的角度来看,如果微软不再进一步增强它,我也没有任何问题,因为我需要的功能已经足够了。
现在我的问题是,我应该使用LINQ to SQL还是坚持使用传统的架构?
另外,是否还有其他选择?
编辑:我将使用SQL Server作为数据库,并且不需要与任何其他数据库进行交互。
设计DAL层最重要的目标之一是更快的开发和维护未来的数据库表更改,因为未来字段可能会增加或减少。
如果您觉得任何ORM工具真的很好,并且没有陡峭的学习曲线,那么我们也可以使用它。
请提供建议。

有趣的是,“微软不会支持或增强LINQ to SQL”。有任何链接吗? - Saar
这是我在几个博客中听到的,但今天刚刚得到了这个链接...我对此更加困惑了。http://damieng.com/blog/2009/06/01/linq-to-sql-changes-in-net-40 - Harryboy
2
正如您从此链接 http://damieng.com/blog/2009/06/01/linq-to-sql-changes-in-net-40 中所看到的,Linq-to-SQL 在 .NET 4 中仍然得到了完全支持,并且甚至进行了扩展和错误修复。关于Linq-to-SQL不再得到支持的所有传言都是虚假的 - marc_s
6个回答

2

由于您正在开展中等规模的项目,我建议您使用LINQ-TO-SQL,因为它具有以下优点:

LINQ to SQL的优点:

•没有像SQL查询中那样的魔术字符串 •智能提示 •当数据库更改时进行编译检查 •更快的开发速度 •工作单元模式(上下文) •可用于小型项目的自动生成域对象 •惰性加载 •学习编写Linq查询/lambda表达式是.NET开发人员必须学习的内容。 关于性能:

•在大多数解决方案中,性能很可能不会成为问题。过度优化是一种反模式。如果您后来发现应用程序的某些部分太慢,可以分析这些部分,并在某些情况下甚至用存储过程或ADO.NET替换一些Linq查询。 •在许多情况下,惰性加载功能可以加快性能,或者至少大大简化代码。 关于调试:

•在我看来,调试Linq2Sql比存储过程和ADO.NET都要容易得多。我建议您查看Linq2Sql Debug Visualizer,它使您可以查看查询,并在调试时触发执行以查看结果。 •您还可以配置上下文将所有SQL查询写入控制台窗口,更多信息请参见此处。 关于另一个层:

•Linq2Sql可以看作是另一层,但它是纯数据访问层。存储过程也是另一层代码,我已经看到很多情况下业务逻辑的一部分已经实现在存储过程中。在我看来,这样做更糟糕,因为您将业务层拆分成两个位置,开发人员将更难以清晰地了解业务领域。


LINQ允许你这样做,而LINQ2SQL只是其中的一种实现。你不需要使用LINQ2SQL才能使用LINQ2XML或LINQ2Objects。这是微妙但重要的区别。 - Martijn Laarman

1

编写DAL没有绝对的首选方式。这些都是选项。选择哪种取决于您的项目、技能和倾向。

通常情况下,使用LINQ可以提高生产力。另一方面,使用存储过程构建的DAL可以期望具有更快的性能。

问题只会在您需要一些特定查询时出现,而默认的LINQ to SQL提供程序无法生成足够快的查询时。在这种情况下,您将不得不利用您的LINQ代码,在需要时插入自定义存储过程。

关于LINQ to SQL的支持和进一步开发,它早已停止了很长时间。因此没有官方的进一步开发。注意:这适用于LINQ to SQL(它将被EF接管)关系解决方案,而不是主要的LINQ功能。

Entity Framework在其v.1版本中仅收到了大量批评。建议等待v2发布。

LINQ最重要的限制(相对于Entity Framework或任何其他流行的ORM)是它不支持1到n的映射。也就是说,每个LINQ类只能映射到单个表,不能表示多个表的某种视图。也许对您来说不重要,但也可能很重要。这取决于您的项目。


你能推荐一些不需要陡峭学习曲线的ORM吗? - Harryboy

1
存储过程与ORM的论点是长期存在的,可能不会很快解决。我的建议是使用ORM(在你的情况下使用Linq-to-Sql)。 是的,存储过程将始终更快,因为查询是预编译的。你真正需要问自己的问题是,你是否有一个性能密集型系统,你的用户会注意到这种差异。请记住,使用存储过程意味着你需要手动编写所有自己的查询,而使用ORM则可以为你完成此操作。这通常意味着ORM将加速你的开发。 既然你提到加快开发时间是你的目标之一,我建议使用Linq-to-Sql - 否则你将基本上编写整个DAL。

1

你提供的所有选项都有显著的缺点。它们都不符合你设定的要求。

你需要优先考虑什么对你最重要。

如果学习曲线是你最大的问题,那么如果你已经熟悉ADO.NET、DataTables等技术,就应该避免使用所有ORM。

如果开发速度是你最大的问题,那么你应该学习一种ORM并采用这种方式。最容易推荐的ORM是NHibernate。其他所有ORM都有显著的弱点。NHibernate适用于绝大多数项目,而其他ORM则更具情境适用性(取决于你的数据库设计、模型设计、敏捷性要求、遗留架构支持等)。所有ORM都有学习曲线,只是在不同的时间和不同的方式下才会出现。


就LINQ to SQL(或PLINQO)而言,我没有任何学习曲线,开发速度也很快,你的意见是什么? - Harryboy
这并不是我使用LinqToSql的经验。如果你认为LinqToSql能够给你两全其美,那就去试试吧。最终你可能还需要转向NHibernate。LinqToSql的特性非常少,有些本应该容易的事情在LinqToSql中却很困难。 - Michael Maddox
你能提供任何比较LINQ to SQL和nHibernate ORM的链接吗? - Harryboy
这个链接会带你去很多.NET ORM的比较:http://stackoverflow.com/questions/1377236/nhibernate-entity-framework-active-records-or-linq2sql - Michael Maddox
尽管出于各种原因(如时间限制和学习曲线),我目前的项目只限于使用LINQ to SQL,但我已经开始探索NHibernate,并且我的第一印象是它真的很好。我正在使用以下链接summerofnhibernate.com以及《nhibernate-in-action》(书)+1给你。 - Harryboy

0

仅仅是为了扩展@Developer Art的观点,使用传统的存储过程方法可以让你将业务逻辑放在数据库中。通常情况下,你会想要避免这样做,但有时候确实需要这样做。更不用说,你还可以使用这种方法在数据库层面上强制执行约束和权限。这完全取决于你的需求。


做这件事很烦人,它让理解代码、版本控制和重构变得非常困难。 - mcintyre321
你说不应该把业务逻辑放在数据库中,但你仍然推荐这样做? - Jaco Pretorius
不,那不是我说的-回去再读一遍答案。我不是它的粉丝,但有几次我遇到了必须将某些业务逻辑放入数据库中的情况。你可以讨厌它(就像我说的,我个人不喜欢它),但有时它是最好的答案。业务规则可以以触发器的形式存在-在业务层严格执行这种操作是很困难的。 - slugster
任何直接说“做这件事很糟糕”的人都没有考虑到所有的角度。理解代码并不更加困难 - 无论在哪里,你的代码都应该有良好的注释和明确的意图。版本控制可能是一个问题,但如果你的业务规则经常变化,那么你应该使用规则引擎,而不是将它们埋藏在编译代码或数据库中。 - slugster

-1

考虑到所提到的限制,我建议只使用自定义查询和ADO.NET,而不要使用任何花哨的东西。此外,基于存储过程的数据访问层更快是一种基于错误论点的观念,例如存储过程是预编译的,但实际上它们并不是。它们只有查询计划缓存。因此,您在存储过程中的投资越少,您就越好。我的建议是使用ADO.Net和从实体对象构建的自定义动态查询。


那么您建议在代码中使用字符串拼接来构建SQL语句...? - Greg Beech
是的,根据提到的问题,这并不是很大的开销,因为他的应用程序并不是非常庞大的,而且它总是可以保持简单。 - codegoblin
请阅读关于存储过程预编译神话的内容。存储过程并不比其他查询更快,事实上,在长期运行中它们还会带来一些麻烦,并且也不是很容易更改。像其他任何查询一样,存储过程拥有查询缓存计划并且已经预编译了。因此,认为它们是更快的是天真的。我在下面提供了有关书籍在线的链接以获取详细信息:http://msdn.microsoft.com/en-us/library/ee343986.aspx - codegoblin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接