【问题标题】:C#: SQL Query Builder ClassC#:SQL 查询生成器类
【发布时间】:2011-11-02 13:47:29
【问题描述】:

我在哪里可以找到一个好的 SQL 查询构建器类。我只需要一个简单的类来构建一个 SQL 字符串,就是这样。我将需要它用于 C# 和 MySql。我真的不需要像 Linq 或 NHibernate 这样的东西。谢谢

【问题讨论】:

标签: c# mysql


【解决方案1】:

您可能可以使用框架类 CommandBuilder。签出:

http://msdn.microsoft.com/en-us/library/tf579hcz.aspx

【讨论】:

    【解决方案2】:

    如果您使用 .NET 4 并且不介意使用动态,您可以使用由 Rob Conery 创建的 Massive,这个单文件数据库不需要 dll,只需删除 Massive.cs 文件即可开始使用。

    您可以使用 Massive 来构建这样的查询。

    //grab all the products
    var products = table.All();
    //Or
    var productsFour = table.All(columns: "ProductName as Name", where: "WHERE categoryID=@0",args: 4);
    

    您还可以根据需要运行临时查询:

    var result = tbl.Query("SELECT * FROM Categories");
    

    【讨论】:

    • 您好 Jethro,我查看了文档并没有看到它支持 MySql。你知道他们是否支持MySql?
    • @Luke101,原来的Massive好像不支持MySql,但是如果你查看这个链接nyqui.st/massive-data-access-for-mysql你会看到有人已经添加了使用MySql的功能。 :) 您可以使用 NuGet 并查找 Massive.MySql
    【解决方案3】:

    我使用这个代码..它也转义了字符串我希望它有帮助:

     class Mysql
    {
        public static string INSERT(string INTO, NameValueCollection VALUES)
        {
            string queryString = "INSERT INTO " + INTO + " (";
            for (int i = 0; i < VALUES.Count; i++)
            {
                queryString += VALUES.Keys[i] + (i + 1 == VALUES.Count ? "" : ",");
            }
            queryString += ") VALUES (";
    
            for (int i = 0; i < VALUES.Count; i++)
            {
                queryString += Escape(VALUES[VALUES.Keys[i]]) + (i + 1 == VALUES.Count ? ("") : (","));
            }
            queryString += ");";
            return queryString;
        }
        public static string DELETE(string FROM, NameValueCollection WHERE)
        {
    
            string queryString = "DELETE FROM " + FROM + " WHERE";
            for (int i = 0; i < WHERE.Count; i++)
            {
                queryString += " " + WHERE.Keys[i] + "=" + Escape(WHERE[WHERE.Keys[i]]);
    
            }
    
            queryString += ";";
            return queryString;
        }
        public static string UPDATE(string UPDATE, NameValueCollection SET, NameValueCollection WHERE)
        {
    
            string queryString = "UPDATE " + UPDATE + " SET";
            for (int i = 0; i < SET.Count; i++)
            {
                queryString += " " + SET.Keys[i] + "=" + data.Escape(SET[SET.Keys[i]]) + (i + 1 == SET.Count ? ("") : (","));
    
            }
            queryString += " WHERE";
            for (int i = 0; i < WHERE.Count; i++)
            {
                queryString += " " + WHERE.Keys[i] + "=" + data.Escape(WHERE[WHERE.Keys[i]]);
    
            }
            queryString += ";";
            return queryString;
    
        }
        public static string SELECT(string[] SELECT, string FROM, NameValueCollection WHERE)
        {
    
            string queryString = "SELECT ";
    
            for (int i = 0; i < SELECT.Length; i++)
            {
                queryString += SELECT[i] + (i + 1 == SELECT.Length ? ("") : (","));
    
            }
            queryString += " FROM " + FROM + " WHERE ";
            for (int i = 0; i < WHERE.Count; i++)
            {
                queryString += " " + WHERE.Keys[i] + "=" + Escape(WHERE[WHERE.Keys[i]]);
    
            }
    
            queryString += ";";
            return queryString;
    
        }
        public static string Escape(string input)
        {
            using (var writer = new StringWriter())
            {
                using (var provider = CodeDomProvider.CreateProvider("CSharp"))
                {
                    provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, null);
                    return writer.ToString();
                }
            }
        }
    }
    

    你可以这样使用它:

            NameValueCollection nvc_for_SET_and_VALUES=new NameValueCollection();
            NameValueCollection nvc_for_WHERE= new NameValueCollection();
            nvc_for_WHERE.Add("arg1","value1");
            nvc_for_WHERE.Add("AND arg2","value2");
            nvc_for_WHERE.Add("OR arg2","value3");
            nvc_for_SET_and_VALUES.Add("arg", "value");
            nvc_for_SET_and_VALUES.Add("arg2", "value2");
            string[] fieldsToSelect= { "arg1", "arg2" };
            Mysql.DELETE("mytable", nvc_for_WHERE);
            Mysql.INSERT("mytable", nvc_for_SET_and_VALUES);
            Mysql.SELECT(fieldsToSelect, "mytable", nvc_for_WHERE);
            Mysql.UPDATE("mytable", nvc_for_SET_and_VALUES, nvc_for_WHERE);
    

    【讨论】:

    • 我快哭了,不要使用字符串连接来构建查询,而是使用 Command 和 Parameter 对象。这是一个可能的 SQL 注入漏洞。 imperva.com/resources/glossary/sql_injection.html
    • 此代码声称已从 SQL 注入攻击中清除,但我完全不确定该清除是如何工作的。我不明白如何从参数构建 C# 表达式,然后通过 CodeDom 运行它使其卫生。
    【解决方案4】:

    Mohammed Hadi,DbExtensions 您的样本可以是这样的:

        public static string InsertQuery(string into, NameValueCollection values)
        {
            var query = SQL
                .INSERT_INTO(into + " (" +
                             String.Join(" ,", values.Keys.Cast<String>().ToArray()) + 
                             ")")
                .VALUES(values.Keys.Cast<String>().Select(key => values[key]));
    
            return query.ToString();
        }
    

    【讨论】:

      【解决方案5】:

      由于 Google 将我引导至此页面, 我建议SqlKata,一个简单但功能强大的 SqlQuery Builder,它支持嵌套 where 条件、子查询和连接。

      目前支持SqlServer、MySql和PostgreSql

      var query = new Query("Users")
           .LeftJoin("Countries", "Users.CountryId", "Countries.Id")
           .Where("Status", "blocked")
           .OrWhereIn("Id", new [] {10, 11, 12})
           .OrWhere("LastLogin", ">", DateTime.UtcNow.AddMonths(-5));
      

      注意:我是它的所有者

      不同编译器输出的区别
      MySql:https://sqlkata.com/playground/mysql?code=var%20query%20=%20new%20Query(%22Posts%22).Limit(10).Offset(20)%3B

      SqlServer: https://sqlkata.com/playground/sqlserver?code=var%20query%20=%20new%20Query(%22Posts%22).Limit(10).Offset(20)%3B

      甲骨文: https://sqlkata.com/playground/oracle?code=var%20query%20=%20new%20Query(%22Posts%22).Limit(10).Offset(20)%3B

      【讨论】:

      • 这是一个有趣的智力练习,但我想知道为什么要这样做而不是直接编写参数化 SQL。
      • @RobertHarvey 处理对象比处理字符串容易得多,你也可以从数据库抽象层中受益,例如检查sqlkata.vivida-apps.com/?sql--sqlsrv#offsetsqlkata.vivida-apps.com/?sql--mysql#offset
      • 可以在.net 2.0中使用/移植吗
      • 我正在寻找一种动态创建表格的方法。在网页上,用户可以创建一个对象(例如 TodoItem)并为该对象添加字段(Responsible、dueDate、枚举(isDone、isOpen、isInProgress))。网页应将所有这些作为字符串发布到服务器,服务器应创建一个包含匹配列的表。 Knex.js 可以做到这一点 createTabletable.stringtable.string('Title', [150]) 将添加一个名为 Title 的列,长度为 150。
      猜你喜欢
      • 1970-01-01
      • 2011-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多