在ASP.NET应用程序中完全避免特殊sql是一种好做法吗?

在ASP.NET应用程序中完全避免特殊sql是一种好做法吗?,asp.net,sql,sql-server,database-design,stored-procedures,Asp.net,Sql,Sql Server,Database Design,Stored Procedures,相反,只创建存储过程并从代码中调用它们?这里没有正确或错误的答案。两者都有好处,可以通过谷歌搜索轻松获得。不同需求的不同项目可能会导致不同的解决方案。它不是你想要的那样黑或白。你也可以把它加入到混合中。如果您更喜欢数据层中的sql查询而不是存储过程,请确保使用参数化查询 动态SQL-错误 存储过程-更好 Linq到SQL或Linq到EF(或ORM工具)-最佳 您不希望在应用程序中使用动态SQL,因为您没有编译时检查。存储过程至少会被检查,但它仍然不是内聚usnit的一部分,并将业务逻辑删除到数据

相反,只创建存储过程并从代码中调用它们?

这里没有正确或错误的答案。两者都有好处,可以通过谷歌搜索轻松获得。不同需求的不同项目可能会导致不同的解决方案。它不是你想要的那样黑或白。你也可以把它加入到混合中。如果您更喜欢数据层中的sql查询而不是存储过程,请确保使用参数化查询

  • 动态SQL-错误
  • 存储过程-更好
  • Linq到SQL或Linq到EF(或ORM工具)-最佳

  • 您不希望在应用程序中使用动态SQL,因为您没有编译时检查。存储过程至少会被检查,但它仍然不是内聚usnit的一部分,并将业务逻辑删除到数据库层。Linq To EF将允许业务逻辑留在您的应用程序中,并允许您在编译时检查语法。

    完全取决于您在做什么

    一般来说,与动态生成的SQL语句相比,存储过程将更好地缓存其查询计划。维护的索引也会稍微容易一些

    但是,动态生成的SQL语句可以缓存它们的查询计划,因此差别不大

    动态生成的SQL语句还可能引入安全风险—始终将其参数化

    也就是说,存储过程是维护和更新的难点,它们将数据库逻辑和.Net代码分开,这使得开发人员很难将数据访问方法的功能组合起来

    此外,要修复或更新SQL字符串,只需更改代码即可。要修复或更新存储过程,您必须更改数据库,这通常是一个更混乱的选项


    因此,我不建议将其作为“一刀切”的最佳做法。

    这取决于表中的数据分布。准备好的查询计划和存储过程会被缓存,而计划本身取决于表统计信息

    假设您正在构建一个博客,并且您的posts表有一个用户id。并且您经常做一些事情,例如:

    select posts.* from posts where user_id = ? order by published desc limit 20;
    
    假设文章(用户id)和文章(发布描述)上的索引

    另外,假设您有两位作者,author1很久以前写了3篇文章,author2从那时起已经写了10万篇文章

    在这种情况下,临时查询的查询计划将非常不同,具体取决于您是获取author1帖子还是author2帖子:

    • 对于author1,数据库将决定对用户id使用索引并对结果进行排序
    • 对于author2,数据库将使用published上的索引读取前20行

    如果您准备了报表,计划者将从两个报表中选择一个。假设第二个(我认为可能是这样):应用于author1,这意味着通过索引遍历整个表——这比最佳计划慢得多。

    动态SQL和/或特殊SQL有一席之地,但需要根据特定的使用需求进行调整

    到目前为止,存储过程是几乎所有情况下的最佳实践,应该首先考虑

    这个问题比procs或ad hoc稍微大一些,因为数据库有各种各样的工具来定义它的接口,包括表、视图、函数和过程

    这里的人提到了执行计划和参数化,但到目前为止,我认为最重要的是,任何依赖于向用户公开基表的技术都意味着您将失去数据库在垂直或水平方向上更改其底层实现或控制安全性的能力。至少,我将只向典型的应用程序/用户/角色公开视图

    在应用程序或用户帐户只能访问EXEC SP的情况下,该帐户甚至不可能希望使用SQL注入形式:“从用户选择名称、密码”或“从用户删除”或“删除表用户”,因为该帐户只有EXEC例如,您可以在SP级别控制列的可见性,而不必拒绝对员工薪资列进行选择


    换句话说,除非您愿意将db_datareader授予public(因为当您LINQ到表时,实际上就是这样做的),那么您的应用程序中需要某种现实的安全性,SPs是唯一的选择,LINQ to视图可能是可以接受的。

    sp中的sql-易于维护,应用中的sql-维护中的痛苦


    跳到sql实例上,修改sp,测试sp,然后部署sp,而不必修改应用程序中的代码,测试sp,然后部署应用程序,这样做会更快更容易。

    如果简单是您的目标,那么ORM将是简单数据库操作的一个很好的实践

    诸如Entity Framework、nHibernate、LINQ to SQL等ORM将管理数据访问层和存储库层的代码创建,并为您提供表示表的强类型对象。这将导致更干净、更易于维护的体系结构


    为更复杂的查询保存存储过程。这是您可以利用高级SQL和缓存查询计划的地方。

    我想您的意思是,而不是。大多数ORM工具,包括Linq,都会生成临时运行时生成的SQL代码。如果始终使用存储过程Linq是标准的最佳做法,那将是一种糟糕的做法。@Keith-那是是我反对Linq to Sql的原因之一,直到其他一些软件工程师做了一项研究,发现Linq生成的Sql也将被缓存。我花了一段时间才说服我,但我终于看到了证据。评论不错。我宁愿在代码中参数化Sql,也不愿使用存储过程。Lin