【问题标题】:SqlDataSource Code Behind Event Order事件顺序背后的SqlDataSource代码
【发布时间】:2012-04-16 04:43:03
【问题描述】:

我在同一页面上有一个 SqlDataSource、一个 Gridview 和一个 DropDownList。 DropDownList 选择与一组 SelectCommandsUpdateCommands 和 DeleteCommand 相关联,因此我可以利用 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() 逻辑,因为我不完全了解与数据绑定相关的事件顺序。

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

【问题讨论】:

  • 有一个名为 Dynamic Data 的内置模板,它随 ASP.Net 开箱即用,通常提供查看、更新、编辑和删除任何表中记录的能力一个数据源。您还可以自定义单个页面、单个操作、字段类型等。在此处查看更多信息:msdn.microsoft.com/en-us/library/ee845452(v=VS.100).aspx
  • 您是否考虑过使用LinqDataSource 和LINQ-To-SQL/等。使用您的数据库?它可以容易得多,因为它会自动处理选择/插入/更新的管道。
  • 即使您不使用动态数据,查看一些有关其工作原理的源代码以了解如何简化代码并利用已构建的-in 用于生成 SQL 语句等的工具。这种事情以前已经做过很多次了,根据你的做法,有更容易和更难的方法。

标签: c# asp.net c#-4.0


【解决方案1】:

编辑:确实,如果您在 GridView 上使用 AutoGenerateColumns="true" 并通过 SqlDataSource 填充,它会自动按名称将控件的值绑定到 SQL 中的适当参数无需任何额外代码即可查询。但是,我们必须使用GetInsertCommand(true) 等,以便命令使用列名(请参阅下面的代码,其中我展示了如何使用SqlCommandBuilder。有一些陷阱,但是正如我在测试中发现的那样:

  • 你需要设置你的GridView的DataKeyNames
  • 您需要在 sqlDS 上设置 OldValuesParameterFormatString="Original_{0}"
  • 如果您只想更新而不比较旧值,则需要在 SqlCommandBuilder 上添加 scb.ConflictOption = System.Data.ConflictOption.OverwriteChanges;
  • 看来,如果您以编程方式在 SqlDataSource 上填充 Select/Update/DeleteCommand,则必须在每次回发时执行此操作。

但是,如果您需要自定义,SqlDataSource 控件会提供事件InsertingUpdatingDeleting,您可以使用这些事件在对数据库执行 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[...] 访问在InsertingDeleting 事件中完成。


请注意,您还可以使用 SqlCommandBuilder 类自动生成适当的删除/插入/更新命令,这样您就不必构建包含所有表的巨大 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;

这当然需要您的所有表都具有可用于生成相关更新和删除语句的主键。如果没有,您将收到有关动态 SQL 生成的异常。即使您因为在数据库引擎上查找架构的运行时成本而不喜欢这种方法,您也可以始终使用 T4 模板预先生成它们,而不是手动输入它们。

【讨论】:

  • 非常感谢! SqlCommandBuilder 中的 .GetInsertCommand(true) 部分是我所缺少的。我正在动态生成一个字符串而不是一个命令!我也计划最终使用 LinqDataSource,但现在我的代码中只有一部分使用了 Linq;我正在更新它。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-18
  • 2010-10-19
  • 2013-02-03
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多