适用于大型应用程序的数据访问策略

时间:2008-11-12 18:37:55

标签: .net stored-procedures vb6 legacy data-access-layer

我即将开始在.NET 3.5sp1中重写VB6应用程序。 VB6应用程序写得很好,数据层完全基于存储过程。我想使用像Linq2SQL / Entity Framework / NHibernate / SubSonic这样自动化的东西。不可否认,除了一次性项目之外,我还没有使用过任何这些工具。

我担心所有这些选择可能带来的潜在问题是速度。例如,现在要检索单行(或整个列表),我使用以下sproc:

ALTER PROCEDURE [dbo].[lst_Customers]
 @intID     INT = NULL
,@chvName   VARCHAR(100) = NULL
AS

SELECT   Customer_id, Name
FROM dbo.Customer
WHERE (@intID IS NULL OR @intID = Customer_id)
 AND (@chvName IS NULL OR Name like ('%' + @chvName + '%'))
ORDER BY name

要在Linq2SQL / Entity Framework / NHibernate / SubSonic中检索单行,这些解决方案是否必须将整个列表下载到客户端并找到我需要的行?

那么,对于具有大型数据域的应用程序,数据访问策略的共识是什么?

6 个答案:

答案 0 :(得分:6)

我将扮演魔鬼的拥护者并建议你至少考虑坚持使用存储过程。这些代表了一大堆代码,您无需重新编写和调试。来自我们自己的This article Joel Spolsky为避免完全重写提出了一个连贯的论点。

鉴于'绿地'项目,您可以使用您想要的东西,而O / R映射器可能是一个不错的选择。但是,您已经说过VB6应用程序编写得很好。如果sprocs编写得很好,那么你可以免费获得一些应用程序并且它已经被调试,而且你可以回收数据库模式并避免数据迁移带来的大部分痛苦。

Fowler的Patterns of Enterprise Application Architecture应该为您提供一些很好的指针,用于设计一个可以很好地与存储过程配合使用而不会导致维护问题的数据访问层。

这在Oracle / Java应用程序上非常常见。许多传统的Oracle应用程序在PL / SQL中都有大量的存储过程代码 - 这是Oracle Forms客户端 - 服务器时代的标准体系结构。通常的做法是在Java中为sprocs编写一个包装器,并在包装​​器之上构建用户界面。

其他一张海报提到,Subsonic可以为sprocs生成包装器。

曾几何时,我有机会做一个数据字典hack,为PL / SQL sprocs生成一个概念验证的Java / JDBC包装器--IIRC只花了一天左右的时间。鉴于它并不难做到,我会惊讶地发现,你可以从现成的东西中做到这一点并没有太多的选择。在紧要关头,写自己的并不是那么难。

答案 1 :(得分:2)

我不能谈论Linq-to-SQL,Entity Framework,也不能说NHibernate,但我爱上了SubSonic。我对它的体验非常积极。

这些工具的工作方式通常是,它们在托管代码中为您构建参数化查询,在类中封装该访问,然后将这些类公开给您的应用程序。完全生成的DAL摇滚。

通过使用参数化查询,您可能“必须将整个列表下载到客户端并找到我需要的行”的问题得到处理。它们支持where子句和其他过滤,以获得您需要的行。你可以做相同的select * from foo,但你不会陷入那种模式。

也就是说,SubSonic确实 - 在开箱即用于直接表/视图访问时 - 关闭整行,在某些情况下可能是一个缺点。但是,通过存储过程进行访问不是问题 - 我无法与其他人交谈,但是SubSonic有助于创建一个封装所有过程的SPs类,允许您将它们称为方法,并返回相应的DataTable,然后您可以根据需要手动解析。还有一些方法可以从procs初始化DAL类列表,因此如果proc返回一个直接匹配表/视图的数据集,你仍然可以使用更清晰的语法,而无需手动处理。

顺便说一句,(顺便说一句,SubSonic让我理解了“为所有事情做出的努力。”我现在通常几乎没有时间像过去那样花时间进行CRUD过程,而且只能用它们进行复杂的报道。但是你的里程可能,实际上会有所不同。)

答案 2 :(得分:1)

我建议使用SubSonic生成访问现有存储过程的所有代码,这样可以减少因新数据访问层而导致回归的机会。然后可以使用SubSonic生成的ActiveRecord类访问任何新功能。在我看来,这是最安全和最快速的方法,

我不同意NHibernate的建议,因为它不适合使用存储过程。

答案 3 :(得分:1)

我们尝试将实体框架用作orm,并在尝试将其与域驱动开发一起使用时遇到了多个问题。 Linq to Sql也有一些限制,微软将在下一版本中停止支持它,我相信。

答案 4 :(得分:1)

如果查询在存储过程中,那么他们很可能已经进行了优化。并且他们可能会为JOINS,子查询等自由使用SQL表达式。

使用ORM类型的抽象层复制那种效率和表现力,准确,我认为这是一个挑战 - 特别是如果你不完全熟悉这些工具。

您可以在完成应用程序的其余部分之后始终重构查询。 ORM世界变化得足够快,当你到达那里时,选项肯定会有所不同。

答案 5 :(得分:0)

SubSonic,即使是作者之一的Rob Connery,也写得更多,以支持快速应用程序开发,而不是大型应用程序。我会说NHibernate,因为你会从社区中找到最多的支持,以及经过验证的真实测试框架。您可以从www.dimecasts.net获取有关设置NHibernate内容的详细信息。