C# 如何检测哪个列';s值已在表中更新

C# 如何检测哪个列';s值已在表中更新,c#,sql-server,C#,Sql Server,假设我的c#项目中有一个包含85个字段的学生注册表,有三个按钮“保存”、“更新”和“删除”。 更新字段的人非常清楚哪个字段已更新,但其他人如何知道哪个字段已更新?因为… 如果我单击“更新”按钮而不更改任何值,则当我单击“更新”按钮并进行一些更改时,将执行更新查询和相同的更新查询。 所以我希望数据库能够检测更新查询中哪个字段已更新。 传统的方法是存储以前的值,然后逐个字段将它们与新值进行比较。但这会降低性能 有什么聪明的方法吗?我有一种方法可以做到这一点,使用表版本控制,您可以维护每次更新、创建和

假设我的c#项目中有一个包含85个字段的学生注册表,有三个按钮“保存”、“更新”和“删除”。
更新字段的人非常清楚哪个字段已更新,但其他人如何知道哪个字段已更新?因为…
如果我单击“更新”按钮而不更改任何值,则当我单击“更新”按钮并进行一些更改时,将执行更新查询和相同的更新查询。

所以我希望数据库能够检测更新查询中哪个字段已更新。

传统的方法是存储以前的值,然后逐个字段将它们与新值进行比较。但这会降低性能


有什么聪明的方法吗?

我有一种方法可以做到这一点,使用表版本控制,您可以维护每次更新、创建和删除记录


第二种方法是,您必须添加审计表或字段来存储SQL查询,还必须存储哪些用户更改了数据,还必须像这样存储上次修改的日期。

我有一种方法可以使用表版本控制来实现这一点,您可以使用它来维护每次更新、创建和删除记录


第二种方法是,您必须添加审计表或字段来存储SQL查询,还必须存储哪些用户更改了数据,还必须像这样存储上次修改的日期。

您可以使用
rowversion
列实现乐观并发。这避免了需要单独检查每列的旧/新值。在UPDATE语句的WHERE子句中指定原始行版本,并验证行是否已更新。过程示例:

CREATE TABLE dbo.OptimisticConcurrencyExample(
    OptimisticConcurrencyExampleID int NOT NULL 
        CONSTRAINT PK_OptimisticConcurrencyExample PRIMARY KEY
    , Column1 int NOT NULL
    , Column2 int NOT NULL
    , Column3 int NOT NULL
    , RowVersion rowversion
);
GO

CREATE PROC dbo.UpdateOptimisticConcurrencyExample
      @OptimisticConcurrencyExampleID int
    , @Column1 int
    , @Column2 int
    , @Column3 int
    , @OriginalRowVersion rowversion
AS
UPDATE dbo.OptimisticConcurrencyExample
SET
      Column1 = @Column1
    , Column2 = @Column2
    , Column3 = @Column3
WHERE
    OptimisticConcurrencyExampleID = @OptimisticConcurrencyExampleID
    AND RowVersion = @OriginalRowVersion;

IF @@ROWCOUNT = 0
BEGIN
    RAISERROR('data updated or deleted by another user', 16, 1);
END
GO
当出现乐观并发错误时,应用程序代码可以使用当前值刷新数据,让用户知道其他人更新了行,并允许用户重新输入更改。您可以通过透明的方式合并代码中挂起的更改(检查每列的新旧值),并仅在发生冲突时通知用户。类似地,在与输入值和当前值以及标记的不同值发生冲突后,您可以向用户提供一个合并表单,等等


但是由于冲突通常很少发生(不同的用户不太可能同时更新同一个学生记录),因此额外的开发工作可能不值得费心

您可以使用
rowversion
列实现乐观并发。这避免了需要单独检查每列的旧/新值。在UPDATE语句的WHERE子句中指定原始行版本,并验证行是否已更新。过程示例:

CREATE TABLE dbo.OptimisticConcurrencyExample(
    OptimisticConcurrencyExampleID int NOT NULL 
        CONSTRAINT PK_OptimisticConcurrencyExample PRIMARY KEY
    , Column1 int NOT NULL
    , Column2 int NOT NULL
    , Column3 int NOT NULL
    , RowVersion rowversion
);
GO

CREATE PROC dbo.UpdateOptimisticConcurrencyExample
      @OptimisticConcurrencyExampleID int
    , @Column1 int
    , @Column2 int
    , @Column3 int
    , @OriginalRowVersion rowversion
AS
UPDATE dbo.OptimisticConcurrencyExample
SET
      Column1 = @Column1
    , Column2 = @Column2
    , Column3 = @Column3
WHERE
    OptimisticConcurrencyExampleID = @OptimisticConcurrencyExampleID
    AND RowVersion = @OriginalRowVersion;

IF @@ROWCOUNT = 0
BEGIN
    RAISERROR('data updated or deleted by another user', 16, 1);
END
GO
当出现乐观并发错误时,应用程序代码可以使用当前值刷新数据,让用户知道其他人更新了行,并允许用户重新输入更改。您可以通过透明的方式合并代码中挂起的更改(检查每列的新旧值),并仅在发生冲突时通知用户。类似地,在与输入值和当前值以及标记的不同值发生冲突后,您可以向用户提供一个合并表单,等等


但是由于冲突通常很少发生(不同的用户不太可能同时更新同一个学生记录),因此额外的开发工作可能不值得费心

为什么需要保存按钮和更新按钮?同样的事情,对吗

修改程序中的逻辑,仅当用户 更改学生注册表中相对于 数据库中的数据

  • 从数据库中读取记录
  • 将记录数据存储在本地
    数据行
    列表
  • 将数据加载到学生注册表中
  • update_button.enable=false
  • delete_button.enable=true

  • 为学生注册表上的每个
    TextBox
    创建
    TextChange
    事件方法

  • 当触发
    TextChange
    事件方法时,将
    TextBox
    文本与相应的
    DataRow
    字段或
    列表
    项(大小写)进行比较 不敏感)

  • 如果它们不匹配,请启用
    更新按钮

  • 如果用户单击
    更新按钮
    ,则更新记录并禁用
    更新按钮


为什么需要保存按钮和更新按钮?同样的事情,对吗

修改程序中的逻辑,仅当用户 更改学生注册表中相对于 数据库中的数据

  • 从数据库中读取记录
  • 将记录数据存储在本地
    数据行
    列表
  • 将数据加载到学生注册表中
  • update_button.enable=false
  • delete_button.enable=true

  • 为学生注册表上的每个
    TextBox
    创建
    TextChange
    事件方法

  • 当触发
    TextChange
    事件方法时,将
    TextBox
    文本与相应的
    DataRow
    字段或
    列表
    项(大小写)进行比较 不敏感)

  • 如果它们不匹配,请启用
    更新按钮

  • 如果用户单击
    更新按钮
    ,则更新记录并禁用
    更新按钮


您可以在类中实现INotifyPropertyChanged,并以这种方式跟踪什么样的c#项目?您使用的是什么数据结构?更改跟踪内置于数据表和表单中。您可以在类中实现INotifyPropertyChanged,并以这种方式跟踪什么样的c#项目?您使用的是什么数据结构?更改跟踪内置于数据表和ORM之类的东西中。