2016-04-21 69 views
1

如何在C#中使用动态查询?从我已经搜索过的类似到当我们使用带有参数的SqlCommand来防止sql注入(下面的例子)。c#,使用动态查询

using (SQLiteConnection DB_CONNECTION = new SQLiteConnection(connectionString)) 
     { 
      DB_CONNECTION.Open(); 
      string sqlquery = "UPDATE table SET Name [email protected], [email protected] WHERE Key [email protected];"; 
      int rows = 0; 
      using (SQLiteCommand command = new SQLiteCommand(sqlquery, DB_CONNECTION)) 
      { 
       SQLiteParameter[] tableA = { new SQLiteParameter("@Key", todo.Key), new SQLiteParameter("@Name", table.Name), new SQLiteParameter("@IsComplete", table.IsComplete) }; 
       command.Parameters.AddRange(tableA); 
       rows = command.ExecuteNonQuery(); 
      } 
      DB_CONNECTION.Close(); 
      return (rows); 
     } 

我是新来的C#和我想知道我怎么能做到这一点,在此先感谢。

+4

它可能会更好,请问怎么解决,你认为动态查询就能解决问题。 – spender

+0

我有一个项目,我必须从一个ERP管理数据,并被告知使用动态查询来编辑数据 – Esteves

+0

我已经在下面发布了一个答案,以建议如何增加上面的示例以构建基于一个特定的变量是空字符串还是空格。我还使用实体框架编写了一个更现代的示例。 –

回答

0

基本上只是基于一组条件建立字符串sqlQuery,并确保已设置适当的参数。例如,这里是一些伪C#(不是错误测试):

//Set to true, so our queries will always include the check for SomeOtherField. 
//In reality, use some check in the C# code that you would want to compose your query. 
//Here we set some value we want to compare to. 
string someValueToCheck = "Some value to compare"; 

using (SQLiteConnection DB_CONNECTION = new SQLiteConnection(connectionString)) 
{ 
    DB_CONNECTION.Open(); 
    string sqlquery = "UPDATE MyTable SET Name [email protected], [email protected] WHERE Key [email protected]"; 

    //Replace this with some real condition that you want to use. 
    if (!string.IsNullOrWhiteSpace(someValueToCheck)) 
    { 
     sqlquery += " AND SomeOtherField = @OtherFieldValue" 
    } 

    int rows = 0; 
    using (SQLiteCommand command = new SQLiteCommand(sqlquery, DB_CONNECTION)) 
    { 
     //Use a list here since we can't add to an array - arrays are immutable. 
     List<SQLiteParameter> tableAList = { 
      new SQLiteParameter("@Key", todo.Key), 
      new SQLiteParameter("@Name", table.Name), 
      new SQLiteParameter("@IsComplete", table.IsComplete) }; 

     if (!string.IsNullOrWhiteSpace(someValueToCheck)) { 
      //Replace 'someValueToCheck' with a value for the C# that you want to use as a parameter. 
      tableAList.Add(new SQLiteParameter("@OtherFieldValue", someValueToCheck)); 
     } 

     //We convert the list back to an array as it is the expected parameter type. 
     command.Parameters.AddRange(tableAList.ToArray()); 
     rows = command.ExecuteNonQuery(); 
    } 
    DB_CONNECTION.Close(); 
    return (rows); 
} 

在这个时代,它很可能是值得研究的LINQ到实体,因为这将帮助你在动态撰写查询您的代码 - 例如https://stackoverflow.com/a/5541505/201648

要设置现有数据库 - 也被称为“数据库优先” - 见下面的教程: https://msdn.microsoft.com/en-au/data/jj206878.aspx

您可以跳过步骤1,因为你已经有一个数据库,还是先做好整个教程为实践。

下面是一些伪C#LINQ代码来大致执行相同的更新与前面的例子:

//The context you have setup for the ERP database. 
using (var db = new ERPContext()) 
{ 

    //db is an Entity Framework database context - see 
    //https://msdn.microsoft.com/en-au/data/jj206878.aspx 
    var query = db.MyTable 
     .Where(c => c.Key == todo.Key); 

    if (!string.IsNullOrWhiteSpace(someValueToCheck)) 
    { 
     //This where is used in conjunction to the previous WHERE, 
     //so it's more or less a WHERE condition1 AND condition2 clause. 
     query = query.Where(c => c.SomeOtherField == someValueToCheck); 
    } 

    //Get the single thing we want to update. 
    var thingToUpdate = query.First(); 

    //Update the values. 
    thingToUpdate.Name = table.Name; 
    thingToUpdate.IsComplete = table.IsComplete; 

    //We can save the context to apply these results. 
    db.SaveChanges(); 

} 

有参与实体框架一些设置,但在我的经验,语法是更容易跟踪和你的生产力会增加。希望这能让你走上正轨。

LINQ到的entites也可以映射SQL存储过程,如果有人一个团队对象使用它的性能方面的原因:

https://msdn.microsoft.com/en-us/data/gg699321.aspx

,或者如果你绝对UST在C#代码编写自定义查询,这也是允许在实体框架:

https://msdn.microsoft.com/en-us/library/bb738521(v=vs.100).aspx