3

之前,我问我的问题,我想让你知道我对 C# 中的 winforms 很陌生。:) 所以,我正在尝试使用 C# 创建一个 winform,为了从后端获取数据,我将所有 SQL 查询存储在一个 .txt 文件中。在 .txt 文件中输入我的 SQL 查询的格式如下:

// Caption

Query

end

因此,在我的代码中,我开始循环读取文件并读取,直到获得所需的标题。有一次,我得到我的标题,我开始逐行阅读查询,直到我到达“结束”。得到查询后,我明确替换查询中的变量(因为我知道查询是否有变量)。例如,

// Caption 1

Select * from table_1 where col1 = var1;

end

在这种情况下,我阅读了查询并使用 string.Replace() 将“var1”替换为 var1.ToString()。然后,执行查询。

我的问题是,有没有更好的方法来做到这一点?比如,有没有更好的格式来将查询存储在 .txt 文件中?任何建议将不胜感激。谢谢你。

4

4 回答 4

6

警告:我实际上不会这样做,但这里试图回答这个问题。我的官方立场在底部。

如果我正确阅读了您的问题,那么您实际上是在“解析”文本文件以获取所需的查询。如果是这种情况,我强烈建议不要使用直接text来完成此任务。您需要某种结构,以便程序知道“如何”获取适当的信息。 标记语言基本上是允许程序导航文档的结构化文本。

有许多标记可以使用,这里有一些可以满足您的需求。

  1. 如果你想把它保存在一个文件.txt中,并保持它非常简单,你可以尝试使用类似 toml 的东西,然后用toml.net或类似的东西解析它
  2. 更优选的方法是使用JSON(也是文本),然后使用JSON.NET解析数据。
  3. 最后,您可以使用XML并使用XmlReader

现在,因为您需要解析数据,您应该创建一个模型来存储这些信息。

// note this is a JSON example, but you can replace it with whatever Markup parser you like.
public class SqlQueriesFromJsonModel {
    public class Query{
        public string Caption { get; set; }
        public string Query { get; set; }
    }

    public List<Query> Queries{ get; set; }
}

从这里,您想从文件中读取数据,并将其解析为您的模型对象。

SqlQueriesFromJsonModel getSqlQueries(){
    //  grab the file and parse it using json.net
    return queriesFromJson;
}

调用该方法,并使用所需的查询

// using System.Linq;
var queries = getSqlQueries();
var neededSqlQuery = queries.Where(Query => Query.Caption == "Caption 1");

注意:已在文本编辑器中编写,因此可能不准确。如果我有问题,我愿意编辑。

现在对于实际的文档格式,这里有几个选项(您实际上不必使用其中任何一个……这只是为了让创意源源不断)。

这些都是“文本”格式。

json

{
    "queries": [
        {
            "caption": "Caption 1",
            "query": "select * from someTable"
        },
        {
            "caption": "Caption 2",
            "query": "select * from someOtherTable"
        }
    ]
}

xml

<?xml version="1.0"?>
<queries>
    <query caption="Caption 1">select * from someTable</query>
    <query caption="Caption 2">select * from someOtherTable</query>
</queries>

通俗易懂

title = "SQL Queries"

[Caption 1]
query = "select * from someTable"

[Caption 2]
query = "select * from someOtherTable"

既然已经不碍事了,我想写一个免责声明,即从文件中读取您的查询不是一个明智的计划。相反,编写一个存储库层来处理所有需要的查询,并考虑使用ORM使其连接起来更容易、更安全。

如果您对存储库和 ORM 不感兴趣,请至少在数据库的存储过程中编写参数查询

无论哪种方式,您都应该将文本文件完全排除在外.. imo

于 2013-05-22T19:51:58.727 回答
1

我实际上并不反对这种模式——虽然它很不寻常,但它确实有一些好处(我自己有时也做过类似的事情——这不会影响你的意见)。公平地说 - SO(和其他人)上的几乎所有其他人都会建议您使用存储过程和/或 ORM。这当然是主流且毫不奇怪的方法,在打造自己的道路之前,您应该认真考虑它。

无论哪种方式。您绝对应该注意使用参数而不是 string.Replace 的建议。SQL 注入是一个非常容易预防的巨大漏洞——它真的没有任何借口了。

如果您继续将查询存储在文件中,您可能还需要注意性能并考虑缓存查询而不是每次都访问磁盘。根据您的用例,如果文件更改,您可能需要处理使缓存无效 - 存储过程将为您处理。

我也不同意为此使用标记语言的评论。如果您要将它们存储在文本文件中,我建议每个文件进行一个查询。它的版本更好,更清晰,并且在大多数情况下也应该提供更好的性能。

如果您不关心查询的运行时编辑或生产调试,您还可以将它们编译为资源文件(通常用于本地化等事情)。这与 Visual Studio 配合得很好,实现起来相对容易,并且是一种比较常见的方法。

于 2013-05-22T20:58:26.843 回答
1

事实是在某些情况下您不想要存储过程,因为这意味着一方面需要安装才能使用该功能,另一方面您不希望另一层只是为了查询直接服务器或数据库统计。查询实际上是一种资源,而不是代码的一部分。实际上唯一的问题是在哪里存储它,以便它成为应用程序或组件的一部分。因此,资源文件实际上并不是一个坏主意。这里唯一需要决定的是是否以预定义的格式存储它并使用现有的支持代码来管理它或编写你自己的。

@Chase Florell:也许他正在编写存储库层?

于 2014-02-11T09:49:53.700 回答
0

您是否有理由无法使用存储过程将查询保存在数据库中?这通常是存储查询的最佳方式,因为它将数据库逻辑保留在数据库中。

如果没有,您可以将变量列为@varname 并使用 addwithvalue 使用该值填充参数,而不是使用 replace()。

于 2013-05-22T19:51:45.077 回答