C# 事件顺序背后的SqlDataSource代码

C# 事件顺序背后的SqlDataSource代码,c#,asp.net,c#-4.0,C#,Asp.net,C# 4.0,我在同一个页面上有一个SqlDataSource、一个Gridview和一个DropDownList。DropDownList选择与一组SelectCommands、UpdateCommands和DeleteCommands相关联,因此我可以利用GridView AutoGenerateEditButton=“true”和AutoGenerateUpdateButton=“true”机制 Page_Load { switch(ddl.SelectedItem.Text) { c

我在同一个页面上有一个SqlDataSource、一个Gridview和一个DropDownList。DropDownList选择与一组
SelectCommands
UpdateCommands
和DeleteCommands相关联,因此我可以利用GridView AutoGenerateEditButton=“true”和AutoGenerateUpdateButton=“true”机制

Page_Load
{
  switch(ddl.SelectedItem.Text)
  {
     case "A":
       sqlDS.SelectCommand = "Select * From A";
       sqlDS.UpdateCommand = "Update A Set Name = @Name WHERE ID = @ID";
       sqlDS.DeleteCommand = "Delete A WHERE ID = @ID";
       break;
     ...
  }

  sqlDS.DataBind();
  grd.DataSourceID = sqlDS.ID;
  grd.DataBind();
}
我需要如何或在什么时候添加参数?是自动的吗?我基本上只希望能够更新和删除表中的列。我希望在实际的.cs文件中完成所有这些,而不是在.aspx文件中,因为我希望最终使其更具动态性;但现在我只想把基本知识记下来。我怀疑在不适当的事件中可能有DataBind()逻辑,因为我不完全理解与数据绑定相关的事件顺序


查询并不复杂,不涉及连接或视图;它们是对单个表的简单选择。

编辑:如果在GridView上使用AutoGenerateColumns=“true”并通过SqlDataSource进行填充,它会自动将控件的值按名称绑定到SQL查询中的相应参数,而无需任何额外代码。但是,我们必须使用
GetInsertCommand(true)
等,以便命令使用列名(请参见下面的代码,其中我将演示如何使用
SqlCommandBuilder
。但是,正如我在测试中发现的,有一些问题:

  • 您需要设置GridView的
    DataKeyNames
  • 您需要在SQLD上设置
    OldValuesParameterFormatString=“Original_{0}”
  • 如果只想在不比较旧值的情况下进行更新,则需要在
    SqlCommandBuilder
    上设置
    scb.ConflictOption=System.Data.ConflictOption.OverwriteChanges;
  • 如果要以编程方式在SqlDataSource上填充Select/Update/DELETE命令,则必须在每次回发时执行此操作
但是,如果需要自定义,
SqlDataSource
控件提供事件
插入
更新
删除
,在对数据库执行SQL操作之前,可以使用这些事件填充参数:

sqlDS.Updating += new SqlDataSourceCommandEventHandler(sqlDS_Updating);

protected void sqlDS_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
    e.Command.Parameters["@Name"].Value = // retrieve value from user entry
}
通过
e.Command.Parameters[…]
访问,可以在
插入
删除
事件中执行相同的操作


请注意,您还可以使用
SqlCommandBuilder
类自动生成相应的Delete/Insert/Update命令,这样您就不必构建包含所有表的巨型switch语句。以下是一个示例:

string tableName = ddl.SelectedValue;
string connectionString = ConfigurationManager
    .ConnectionStrings["MyConnectionString"].ConnectionString;
string select = "SELECT * FROM [" + tableName + "]";
SqlDataAdapter sda = new SqlDataAdapter(select, connection);
SqlCommandBuilder scb = new SqlCommandBuilder(sda);

sqlDS.SelectCommand = select;
sqlDS.InsertCommand = scb.GetInsertCommand(true).CommandText;
sqlDS.UpdateCommand = scb.GetUpdateCommand(true).CommandText;
sqlDS.DeleteCommand = scb.GetDeleteCommand(true).CommandText;

当然,这需要所有表都有主键,可用于生成相关的update和delete语句。如果没有主键,则会出现有关动态SQL生成的异常。即使您不喜欢这种方法,因为在数据库引擎上查找架构的运行时成本太高,您也可以始终使用它使用T4模板对所有记录进行评分,而不是手动输入。

ASP.Net自带一个名为“动态数据”的内置模板,它提供了查看、更新、编辑和删除数据源中任何表中记录的功能。您还可以自定义单个页面、单个操作和字段类型,等等。请参阅此处的更多信息:您是否考虑过使用
LinqDataSource
和LINQ To SQL/etc.来处理您的数据库?这可能会容易得多,因为它可以自动处理选择/插入/更新的管道。即使您不使用动态数据,也可以查看一些源代码了解其工作原理让我们来了解如何简化代码,以及如何利用内置工具生成SQL语句等。这种事情以前已经做过很多次了,根据您的操作方式,有很多更简单和更难的方法。非常感谢!GetInsertCommand(true)SqlCommandBuilder中的一部分是我所缺少的。我正在动态生成一个字符串而不是命令!我也计划最终使用LinqDataSource,但现在只有一部分代码使用Linq;不过我正在更新它。再次感谢!