基于LINQ查询构造插入查询

时间:2017-09-25 00:33:03

标签: c#

我正在尝试根据LINQ查询返回的填写文本框的数量构建一个sql插入查询。基本上,文本框的开头从选项卡索引编号13开始,到选项卡索引编号33结束,并将非空文本框添加到keyvaluepair列表。我感到困惑的问题是如何将填写的文本框的值添加到插入查询中的命名参数,而不会出现number of query values and destination fields are not the same的错误。这是我的代码:

 // use LINQ to fetch all the children textboxes based on the ones that are not empty
 System.Collections.Generic.Dictionary<string, string> dictionary = tabCtrl1.TabPages["tabPage1"].Controls.OfType<TextBox>()
    .Where(t => t.TabIndex >= startTabIndex && t.TabIndex <= endTabIndex && !string.IsNullOrWhiteSpace(t.Text))
    .Select(x => new System.Collections.Generic.KeyValuePair<string, string>(x.Name, x.Text))
    .ToDictionary(z => z.Key, z => z.Value);

 // loop through all the children textboxes
 // and assign them to the list members.childTextBoxes
 foreach (System.Collections.Generic.KeyValuePair<string, string> kvp in dictionary)
 {
     members.childTextBoxes.Add(new System.Collections.Generic.KeyValuePair<string, string>($"{kvp.Key}", $"{kvp.Value}"));
 }

然后构造插入查询:

 for (int i = 0; i < members.childTextBoxes.Count; i++)
 {
     using (members.DBCommand = new System.Data.OleDb.OleDbCommand("INSERT INTO children (pid, childName, birthday, childEmail)" +
         "VALUES (" + lastInsertId + ",  @"  + members.childTextBoxes[i].Key + ")", members.DBConnection))
     {
         members.DBCommand.Parameters.AddWithValue("@" + members.childTextBoxes[i].Key, members.childTextBoxes[i].Value);
     }
         // error occurs here. i'm assuming its to do 
         if (members.DBCommand.ExecuteNonQuery() > 0)
         {
              MessageBox.Show("Records inserted", "QBC", MessageBoxButtons.OK);
         }
    } 
}

我希望这是足以描述我感到困惑的问题的信息。

任何帮助都将不胜感激。

谢谢!

我可以尝试添加更多信息,如果它有助于使我的问题更清晰。

更新 -

我继续尝试使用.Add而不是.AddWithValue,但不幸的是,它一直给我插入查询语法错误。

以下是插入查询构建器的更新代码:

 string fieldList = $"{string.Join(",", members.childTextBoxes.Select(tb => mapToDatabase[tb.Key]))}";
 string valueList = $"{string.Join(",", members.childTextBoxes.Select(tb => "?"))}";

 string insertQuery = $"INSERT INTO children {fieldList} VALUES {valueList}";

 using (members.DBCommand = new System.Data.OleDb.OleDbCommand(insertQuery, members.DBConnection))
 { 
     foreach (var field in members.childTextBoxes)
     {
         members.DBCommand.Parameters.Add("@" + field.Key, OleDbType.LongVarChar).Value = field.Value;
     }


     if (members.DBCommand.ExecuteNonQuery() > 0) // error occurs here
     {
         MessageBox.Show("Records inserted", "QBC", MessageBoxButtons.OK);
     }
 }

2 个答案:

答案 0 :(得分:0)

从你在问题中显示的代码中我可以看出最好的,你会想要这样的东西:

var controlMap = new Dictionary<string, string>();
controlMap.Add(nameof(txtChildName), "ChildName");
controlMap.Add(nameof(txtParentName), "ParentName");

string fieldList = $"({string.Join(",", childTextBoxes.Select(tb => controlMap[tb.Key]))})" ;
string valueList = $"({string.Join(",", childTextBoxes.Select(tb => "?"))})";
string insertStatement = $"INSERT INTO children {fieldList} VALUES {valueList}";

var command = new OleDbCommand(insertStatement, members.DBConnection);
foreach (var field in childTextBoxes)
{
    command.Parameters.Add(field.Value);
}

OleDbCommand不支持命名参数,因此您必须使用位置参数。它们标有“?”,并按照它们的使用顺序添加。

您还需要在SQL insert语句中构建字段列表和值列表,以便字段列表中的字段顺序与“?”的顺序相匹配。添加参数时将填充标记。

我无法测试这个,因为我没有完整的设置,但它应该让你非常接近。它假定childTextBoxes被声明为List<KeyValuePair<string, string>>,因为我无法看到您的实际声明。如果不正确,您可能需要稍微调整一下。

答案 1 :(得分:0)

修正了错误,我不得不用括号括起插入值。  string insertQuery = $"INSERT INTO children (pid, {fieldList}) VALUES (?,{valueList})";

修复它。