【问题标题】:C# .NET What's the best way to organize SQL queries and have clean codeC# .NET 组织 SQL 查询并拥有干净代码的最佳方式是什么
【发布时间】:2020-04-16 14:31:06
【问题描述】:

我和我的同事遇到了一个问题。我们有几个 SQL 查询作为字符串。这是一个例子:

    public class Query
{

    public static string CreditTransferId(string expectedValue, string table, int statusId, int messageTypeId, int destination103, int destination202, string StoreStatus202Id)
    {
        return $"SELECT top 1 Id from {table} where MessageId = '{expectedValue}' and FlowId=3 and StatusId={statusId} and MessageTypeId={messageTypeId} and " +
          $" Destination103={destination103} and Destination202={destination202} and StoreStatus103Id is null and StoreStatus202Id {StoreStatus202Id}";
    }
}

现在我们将它们作为字符串从 Query 类中的方法返回。我们想重构代码使其更干净,因为我们有一个方法包含超过 3 个参数,无论如何都很难使用。

你会怎么做呢?组织需要大量参数的 SQL 查询的最简洁方法是什么,就像我们在上面的代码中一样?我非常感谢任何可能改善我们代码当前状态的答案。

谢谢!

【问题讨论】:

  • SQL注入的风险极高。是的,这只是一个返回字符串的方法,但它对参数的有效性进行零检查,使用纯字符串连接并且没有正式的参数定义......它永远不会通过我工作的代码审查。
  • 只是为了澄清:您应该考虑没有数量的有效性检查来保护您免受 SQL 注入;检查输入纯粹是为了查看它们是否在您的预期范围内;为了防止 SQL 注入,你绝对应该使用 parameters;如果您喜欢编写自己的 SQL,Dapper 是执行参数化查询的一种非常方便的方式

标签: c# sql .net coding-style code-cleanup


【解决方案1】:

动态 SQL 一开始是一件非常糟糕的事情,因为它们对 SQL 注入开放,您应该使用参数化查询并返回一个字符串。

"eg: SELECT top 1 Id from [Table] where [MessageId] = @messageId"

所以您不需要传递任何值,您可以将这些值添加到您的 SqlParamater 列表中

表名可能没有意义,因为这与sql有关,所以可能只是将其添加到sql字符串中

这真的不需要额外的类,只需在你调用它的地方创建 sql 变量,所以如果你需要它就在那里?

..或使用存储过程

..或使用实体框架

【讨论】:

    【解决方案2】:

    EF 很棒,您必须决定是否要这样做。有一些不适合的情况。你决定坚持使用纯文本查询如何将查询分成几部分: FromBuilder 加入建造者 组生成器 条件生成器等

    例如:

    return @"
    "+new TableIdSelectorBuilder(table).Get() +@"
    "+new FromBuilder().Get(table) +@"
    "+new TableConditionByIdBuilder(table).Get(I'd)+@"
    ";
    

    编辑: 存储过程允许在不发布新应用程序版本的情况下更改查询,但在活体上工作有点麻烦。至少有时。

    【讨论】:

      猜你喜欢
      • 2019-12-19
      • 2013-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多