C# 动态生成SQL查询
我根据用户输入动态创建文本框,如下所示:C# 动态生成SQL查询,c#,sql,winforms,C#,Sql,Winforms,我根据用户输入动态创建文本框,如下所示: int nbrTextBoxBE = int.Parse(textBoxNbrBE.Text); panelBE.Controls.Clear(); panelBE.Focus(); for (int i = 0; i < nbrTextBoxBE; i++) { TextBox textBoxArticleCodeBE = new TextBox(); TextBox textBoxDesignationBE = new Text
int nbrTextBoxBE = int.Parse(textBoxNbrBE.Text);
panelBE.Controls.Clear();
panelBE.Focus();
for (int i = 0; i < nbrTextBoxBE; i++)
{
TextBox textBoxArticleCodeBE = new TextBox();
TextBox textBoxDesignationBE = new TextBox();
textBoxCArticleCodeBE.Name = "ArticleCodeBE" + (i + 1);
textBoxDesignationBE.Name = "DesignationBE" + (i + 1);
textBoxArticleCodeBE.Text = "";
textBoxDesignationBE.Text = "";
panelBE.Controls.Add(textBoxArticleCodeBE);
panelBE.Controls.Add(textBoxDesignationBE);
panelBE.Show();
}
我尝试使用foreach循环来实现这一点:
foreach (TextBox tb in panelBE.Controls.OfType<TextBox>())
{
// do stuff
}
foreach(panelBE.Controls.OfType()中的文本框tb)
{
//做事
}
当然,它生成的查询数量是我需要的两倍。在这种情况下,虽然不是最干净的解决方案,但您可以通过正常的for
循环轻松实现这一点
var textboxes = panelBE.Controls.OfType<TextBox>();
for(int i=0; i < textboxes.length; i+=2)
{
var articleCodeTextbox = textboxes[i];
var designationCodeTextbox = textboxes[i+1];
//build your query
}
然后,您可以简单地循环所有属于ArticleCodeBE
textbox的文本框,然后您可以像这样从字典中拉出附带的designationdebe
textbox:
Dictionary<TextBox, TextBox> Textboxes = new Dictionary<TextBox, TextBox>();
int nbrTextBoxBE = int.Parse(textBoxNbrBE.Text);
panelBE.Controls.Clear();
panelBE.Focus();
for (int i = 0; i < nbrTextBoxBE; i++)
{
TextBox textBoxArticleCodeBE = new TextBox();
TextBox textBoxDesignationBE = new TextBox();
textBoxCArticleCodeBE.Name = "ArticleCodeBE" + (i + 1);
textBoxDesignationBE.Name = "DesignationBE" + (i + 1);
textBoxArticleCodeBE.Text = "";
textBoxDesignationBE.Text = "";
panelBE.Controls.Add(textBoxArticleCodeBE);
panelBE.Controls.Add(textBoxDesignationBE);
Textboxes.Add(textBoxArticleCodeBE, textBoxDesignationBE);
panelBE.Show();
}
foreach (TextBox articleCodeTB in panelBE.Controls.OfType<TextBox>().Where(tb => tb.Name.Contains("ArticleCodeBE")))
{
var designationCodeTB = TextBoxes[articleCodeTB];
//build your query
}
foreach(panelBE.Controls.OfType()中的文本框articleCodeTB,其中(tb=>tb.Name.Contains(“ArticleCodeBE”))
{
var designationcodeb=文本框[articleCodeTB];
//构建您的查询
}
在这种情况下,更好的解决方案是使用专用控件按照适当的viewmodel方向执行某些操作。您不必再担心如何匹配文本框。完成任务的最正确方法是使用参数集合
// This is assumed to be even
TextBox[] txtArray = panelBE.Controls.OfType<TextBox>().ToArray();
for(int x = 0; x < txtArray.Length; x+=2)
{
TextBox tArticle = txtArray[x];
TextBox tDesignation = txtArray[x+1];
// Where you build the query text
StringBuilder sb = new StringBuilder();
// The placeholders for the parameters to be used
List<string> prmNames = new List<string>();
// The parameter collection
List<SqlParameter> prms = new List<SqlParameter>();
// Initial text for the query
sb.Append("INSERT INTO myTable (ArticleCode, Designation) VALUES (");
prmNames.Add("@p" + tArticle.Name);
prms.Add(new SqlParameter()
{
ParameterName = "@p" + tArticle.Name,
SqlDbType = SqlDbType.NVarChar,
Value = tArticle.Text
});
prmNames.Add("@p" + tDesignation.Name);
prms.Add(new SqlParameter()
{
ParameterName = "@p" + tDesignation.Name,
SqlDbType = SqlDbType.NVarChar,
Value = tDesignation.Text
});
// Concat the parameters placeholders and close the query text
sb.Append(string.Join(",", prmNames) + ")");
// Pass everything to an utility method
// This could be part of a bigger utility database class
ExecuteInsertInto(sb.ToString(), prms);
}
还有一种更好的方法,可以通过对ExecuteInsertInto的单个调用来传递每个命令,但确切的语法取决于数据库类型。简而言之,您可以构建一个包含多个插入的查询文本。有关Sql Server,请参阅
那怎么样:
foreach (TextBox tb in this.Controls.OfType<TextBox>().Where(textbox => textbox.Name.StartsWith("DesignationBE")))
{
//do stuff
}
foreach(this.Controls.OfType()中的TextBox tb,其中(TextBox=>TextBox.Name.StartsWith(“DesignationBE”))
{
//做事
}
增量需要是i+=2
,而不是i++
。这也取决于文本框
列表与添加文本框的顺序完全相同。这很可能是事实,但不能保证是相同的。@关于编辑文本框的顺序更为平坦;我已经提到:)参数化查询的荣誉。你在这里写了半个DAL只是为了解释这个概念。起初我认为你的答案是正确的,但后来我注意到它会生成一个SQL,看起来像这样:插入myTable(ArticleCode,Designation)值(@ArticleCodeBE1,@DesignationBE1,@ArticleCodeBE2,@DesignationBE2,@ArticleCodeBEn,@DesignationBEn)
。。。你需要一个稍微不同的代码来创建值(@p1,p2),(@p3,@p4).
@Steve我试图运行你的代码,但它在使用Append()和Add()方法时返回错误<代码>错误5方法“Add”的无重载包含2个参数和错误2“System.Collections.Generic.List”不包含“Append”的定义,并且找不到接受类型为“System.Collections.Generic.List”的第一个参数的扩展方法“Append”(是否缺少using指令或程序集引用?)
我认为对于调用方和被调用方来说,params SqlParameter[]params
比List prms=null
要好得多。@A.Petit让我在Visual Studio中重写整个过程。如果您不手工编写此代码,您永远不会对Intellisense有足够的欣赏。您正在使用哪些rdbms?
private int ExecuteInsertInto(string query, List<SqlParameter> prms = null)
{
using(SqlConnection cnn = new SqlConnection(..connectionstring goes here..))
using(SqlCommand cmd = new SqlCommand(query))
{
cnn.Open();
if(prms != null)
cmd.Parameters.AddRange(prms.ToArray());
return cmd.ExecuteNonQuery();
}
}
string fieldName = tb.Text.Substring(0, tb.Text.IndexOf("BE"));
foreach (TextBox tb in this.Controls.OfType<TextBox>().Where(textbox => textbox.Name.StartsWith("DesignationBE")))
{
//do stuff
}