【问题标题】:What the most efficient way of monitoring changes to data on an ASP.Net form?监视 ASP.Net 表单上数据更改的最有效方法是什么?
【发布时间】:2012-01-16 17:25:09
【问题描述】:

我有一个 ASP.Net 表单,我想在用户更改数据时发送电子邮件。电子邮件应仅包含已更改的数据,总共大约有 15 个数据字段。

我不想使用 ORM,因为我正在更新一个第三方为我们构建的网站,他们所有的数据访问调用都通过他们的自定义库。

我能想到的唯一方法是

  • 再次调用数据库以获取旧值并逐一比较表单值。如果它们不同,请附加到电子邮件中。

  • 首次加载时将原始数据存储在某处(隐藏字段、会话等),然后再次一次比较一个字段的数据并将差异附加到电子邮件中

  • 让 SO 上的人告诉我有一种更简单和/或更简单的方法,我没有想到

【问题讨论】:

  • 只有你拥有的 asp 页面 - 还是你有权访问它们上使用的数据类?他们实现的 INotifyProperty 是否发生了变化?
  • @ChrisBD 该网站非常基础并且不遵循任何特定的设计模式。数据被拉入ObjectDataSet 并手动应用于需要数据的任何控件。例如,txtFirstName = myDataSet.Tables(0).Rows(0)("FirstName")。这不是我喜欢的做事方法,但我不想重写整个网站,所以我会使用他们已经设置的内容。
  • @Rachel - 您希望电子邮件包含原始值和新值,还是只需要知道字段 更改?
  • @M.Babcock 原始值和新值,以及字段名称

标签: c# asp.net


【解决方案1】:

所有文本框都会有一个TextChanged 事件,您可以让它们将自己标记为已修改。 ComboBox 将有一个SelectedIndexChanged 事件,等等。

编辑:所有更改的事件都可以检查它们的初始值(即使是在恢复的更改中),并将它们自己标记为仍被修改或在恢复时标记为未修改。

【讨论】:

  • 除非已恢复的更改应从列表中排除,在这种情况下,您仍在查看从一个帖子到另一个帖子的持久初始值。
  • 所以您建议将TextChanged 事件连接到每个TextBox,并在该事件中让TextBox 自己设置某种标志来表示它已被修改?这仍然对我没有多大帮助,因为我需要原始值以及更改后的值,而且似乎只会造成巨大的混乱。电子邮件应该只在用户点击保存时才触发,而不是在任何字段发生更改时触发。
  • 是的,但是您不会检查每个值的更改,只检查那些已触发更改事件的值。
  • 我觉得这会使事情复杂化,因为页面上还有其他 PostBacks,所以我认为我必须将更改的数据存储在 PostBacks 之间的 Session 中。此外,在 TextChanged 事件之后,我看不到任何东西可以从 TextBox 获取原始值,所以我认为我必须自己存储它。由于理想情况下我不希望在用户更改数据并恢复为原始值时提交未更改的数据,因此我还必须管理删除已恢复为原始值的数据。似乎对一些没有很多好处的事情进行了很多微观管理
  • @ChuckSavage 你知道吗,我收回了。我试了一下,在让它工作后,它实际上是一个更简单的解决方案,解决了只跟踪更改数据的问题。谢谢你:)
【解决方案2】:

以下是一些可能有用/可能没用的建议:

  • 数据库表上的触发器和触发器比较旧的(使用 DELETED 表)和更新的(使用 INSERTED 表),然后发送电子邮件。这可能可行,也可能不可行,我不是触发器的大力倡导者。
  • 就像您已经说过的,您可以进行另一个数据库调用,这是我推荐的方法。

【讨论】:

    【解决方案3】:

    根据您所说,我认为唯一的方法是在表单上创建一个重复的数据集以存储旧数据并在您想要生成电子邮件的位置运行比较。

    您可以使用Dataset.Copy 复制结构和数据。

    但是,现在我想到它总是有 Datset.GetChanges() 方法和 Dataset.AcceptChanges() 以及 DataSet.HasChanges()

    来自link的示例代码:

    if(dataSet.HasChanges(DataRowState.Modified | 
            DataRowState.Added)&& dataSet.HasErrors)
        {
            // Use GetChanges to extract subset.
            changesDataSet = dataSet.GetChanges(
                DataRowState.Modified|DataRowState.Added);
            PrintValues(changesDataSet, "Subset values");
    
            // Insert code to reconcile errors. In this case, reject changes.
            foreach(DataTable changesTable in changesDataSet.Tables)
            {
                if (changesTable.HasErrors)
                {
                    foreach(DataRow changesRow in changesTable.Rows)
                    {
                        //Console.WriteLine(changesRow["Item"]);
                        if((int)changesRow["Item",DataRowVersion.Current ]> 100)
                        {
                            changesRow.RejectChanges();
                            changesRow.ClearErrors();
                        }
                    }
                }
            }
            // Add a column to the changesDataSet.
            changesDataSet.Tables["Items"].Columns.Add(
                new DataColumn("newColumn"));
            PrintValues(changesDataSet, "Reconciled subset values");
            // Merge changes back to first DataSet.
            dataSet.Merge(changesDataSet, false, 
                System.Data.MissingSchemaAction.Add);
        }
        PrintValues(dataSet, "Merged Values");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 1970-01-01
      • 1970-01-01
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多