是否值得使用ORM与存储过程

时间:2009-07-06 14:28:24

标签: .net-3.5 stored-procedures orm

我公司的政策强制只使用存储过程(SP)与DB通信 (没有动态执行SELECT,应用程序端的VIEWS可用)
业务对象(BO)从DB中获取 使用SQL Reader实现了简单的BO-DB映射器,这看起来效果很好。

表单数据库端我们为每个业务对象提供一个参数化SP,一个SP用于所有CRUD操作,由@MODE参数切换) 所以我们没有像SP_INSERT,SP_UPDATE,SP_SELECT等单独的SP ......

我最近读过很多关于linq2SQL,nHibernate,Subsonic等的内容,看起来非常有趣 我注意到主要的ORM的好处是直接从c#代码执行/过滤的灵活查询 - 在我的话中我不能执行这样的(只允许SP ...)

所以,我想知道 - 如果在我的环境中使用ORM值得吗?
- 你能提到任何好处吗? - 如果是的话 - 你可以推荐什么ORM

您的看法是什么?

7 个答案:

答案 0 :(得分:6)

  

f值得在我的ORM中使用ORM   环境?

恕我直言,可能不是。 ORM专注于对象模型,并基本上尝试将数据库视为哑存储或数据。您的存储过程中可能包含业务逻辑,这与一般原则(或至少约定)有些相反。

至少,您可能会将对象手动映射到存储过程和从存储过程进行映射。

答案 1 :(得分:3)

有人问similar question some time ago - 关于使用ORM来包装遗留存储过程的主体。如果您有这种类型的现有代码库或对架构的政治限制,您可能希望查看其他数据访问机制,看看它们是否会更好地工作。 Fowler的Patterns of Enterprise Application Architecture在为此编制各种选项方面做得很好。

另一种方法是通过政治渠道查看是否可以放宽约束'在ORM无法正常工作的极端情况下使用存储过程,否则使用ORM'。

答案 2 :(得分:2)

我想知道这个“建筑”决定背后的理由是什么。

手动处理低级别的ADO.NET(是的,IDataReader 低级别)几乎不是一个好主意。

NHibernate允许您指定用于查询和修改数据的自定义SQL,但是这样做会损失NHibernate提供的大量功能。

相反,请考虑使用一个简单的结果集映射器,例如BLToolkit,它可以在处理sprocs时解除大部分繁琐的工作。

答案 3 :(得分:2)

我很高兴我不在你工作的地方工作。我接受了非常痛苦的教育,为什么应该避免存储过程,除非它们不久前对于性能或数据完整性原因至关重要。我接受了一个遗留项目。程序源的一半是在Java版本控制下。其中一半作为存储过程嵌入数据库中。您几乎必须拥有DBA权限才能看到它,远程处理它是不可能的。它还与Microsoft SQL Server驱动程序的事务管理器打架。

但话说回来,我曾与之合作的ORM经理对存储过程没有任何问题,只有我。

主要的是,使用ORM的主要原因是为了更容易在卫星服务器上的应用程序中执行“存储过程”,而不是将所有工作转储到数据库服务器上。当然,当所有源代码都在一个地方并使用一种语言时,它也很有用。

答案 4 :(得分:1)

一些(可能全部,我并不完全熟悉所有这些)ORM工具为您提供了一个类来调用您的存储过程。这有助于智能感知,类型,名称等。

SubSonic有这个,我觉得能够调用Project.DAL.SPs.InsertEmployee('John','Doe')而不是构建参数列表非常有帮助。

答案 5 :(得分:1)

使用工具是值得的(即使使用SP)

不完全是ORM工具,但您可以使用其他一些数据访问工具,这样您就可以轻松调用这些存储过程并特别实现其结果。这是这些工具将为您提供极大帮助的地方。想想使用SP所需要做的所有事情:

  • 创建连接和命令
  • 处理连接状态
  • 管理与存储过程名称及其参数相关的字符串(特别是当某人去并改变某些内容时)
  • 执行调用并可能将它们转换为某些对象实例

所有这些都是非常重复的工作,你可以很容易地避免。

我赞成存储过程而非ORM,因为一旦你开始编写一些访问多个表并以任何方式加入它们的更复杂的查询,你就会陷入一大堆麻烦和头痛。与在ORM中必须执行的优化和变通方法相比,复杂的存储过程通常花费更少的时间来编写它(或者至少在某种程度上与实际的存储过程调用相当)。要真正优化某些调用,您必须彻底了解ORM工具。相信我,我一直在使用实体框架(包括非常简化的EF扩展库)。

反正。我建议你看一下 BLToolkit ,这是一个DAL工具而不是实际的ORM工具。我用它来调用我的存储过程并轻松实现其结果。

这个工具实际上使您可以非常简单地透明地使用存储过程。如果您use T4 template我也写过,您可以轻松地避免代码中的魔术字符串(存储过程的名称和参数名称)。模板自动导入存储过程,并使用采用强类型参数的方法创建类(与SP参数的C#等效的C#)。

由于您在单个SP中拥有所有CRUD操作,因此您的SP有点奇怪。如果您愿意,可以更改我的T4模板以为每个SP @Mode调用创建所有四种方法。这会让你感觉很好:

User newUser = db.User.Create(...);
User existingUser = db.User.Get(...);
db.User.Delete(...);
User updatedUser = db.User.Change(...);

如果您不知道我在说什么,您可以查看我的链接博客文章,在那里我解释问题并用T4解决它。

答案 6 :(得分:0)

这种性质的所有主题的正确答案是,“它取决于”。有些事情需要考虑:

  • 你会在sprocs中有业务逻辑吗?
    • 如果是,那么一些注意事项是:
        除非您使用支持轻松开发IOC模式的语言编写sprocs / UDF,否则
      1. IOC 会变得很痛苦。有些数据库允许您使用Java / Perl / Python / C#/ PHP等语言编写sprocs /函数。否则,如果您使用直接SQL,这可能是一个问题。
      2. 确保您知道如何针对sprocs开发单元测试。它实际上并不难,但出于某种原因,有些开发人员似乎认为这是一个问题。
      3. 针对BR违规的sprocs返回错误条件作为返回数据以表达错误代码或异常吗?如果您的策略是为所有违反业务规则的行为冒泡异常,那么您已经做出了一个昂贵的选择。通过另一层(ORM)冒泡异常是一项额外的性能成本 - 您能负担得起吗? (请参阅 http://www.linkedin.com/groups/Throw-Exceptions-vs-Return-Error-4318399.S.132967016,也许 - 但不是那么多: http://sylnsr.blogspot.com/search?q=validation
      4. 是否需要将来自sprocs的错误/异常从内部类型错误消息/代码转换为更加用户友好且可能是不同语言的内容? ORM可能是完美的地方,因为您通过将sprocs生成的内部类型错误/异常“映射”到更加终端用户友好的东西来增加ORM的实用性
    • 如果否,那么剩下的一些注意事项是:
      1. 要花多少工作?是否有ORM框架可以使这个过程无痛/自动化。例如,实体框架使得使用sprocs变得轻而易举。不需要任何手工编码。只需使用向导映射sprocs就可以了。如果设置ORM的工作是> =只是进行本机SQL调用的工作,那么就不要打扰ORM工具(或编写自己的工具,特别是如果你使用的ORDBMS使这更简单)
      2. 您的数据验证政策是什么?如果每个层都负责数据验证,ORM以自动方式提供,那么它就值得。等待流程执行一直到sprocs来验证数据会越多,你的应用程序就越多。
      3. 与#2类似,您的错误/异常处理策略是什么?如果您的应用程序堆栈在所有层中出现异常,那么您的应用程序堆栈具有的层/框架越多,事情也会越来越昂贵。在套牌中添加ORM只会添加另一个遍历图层。
      4. 您的ORM框架有多臃肿? (你关心吗?)一些ORM工具只需从应用程序代码中调用一个sproc就可以在大约4行代码中添加数百行代码。
      5. 你真的知道你的ORM在后台如何运作吗?它会影响性能吗(你关心吗?)每次ORM实例化模型时,我都使用ORM工具检查命名的DB对象(表,sprocs等)。这意味着每次我需要做某事时它都会查询数据库两次。一旦获得要映射的对象的描述,因为它从未缓存地图,再次查询/执行对象。
      6. 您的团队如何管理ORM生成/维护?如果您有幸拥有明亮的 DBA,这将使ORM保持最新状态 - 或 - 有一个自动化流程来保持ORM最新(这就是我的滚动方式)然后是的,ORM很棒,因为你会知道可靠的模型是你唯一需要关心的事情和每个人都会很开心。
      7. 您使用的是MVC吗?谁没有使用MVC?由于您可能(应该)使用MVC,因此通过使用自动方式以您的母语表达sprocs及其结果和模型,您自然会受益匪浅。如果MVC因特定目的而过度杀戮,那么ORM也可能浪费时间。