0

假设我的 C# 应用程序中有一个带有属性A和属性B的TestClass。我通过我的代码更改了B的值,我保持属性A不变。我通过 SimpleRepository 的 Update 方法更新数据库中的 TestClass。

正如我所看到的,它还更新了数据库中的属性A值。

这很容易测试:我在我的应用程序外部(“手动”)更改我的数据库中的值A,然后我从我的应用程序进行更新。属性A的值根据我的应用程序中的 TestClass 状态更改回其值。

所以,我的问题是:是否可以只更新某些属性,而不是 SimpleRepository 的整个类?是否有一些“IgnoreFields”的可能性?

4

2 回答 2

1

您需要的是optimistic concurrency在您的UPDATE声明中,而不是排除某些字段。简而言之,这意味着在更新表时,WHERE会在语句中附加一个子句,以UPDATE确保行中字段的值实际上是上次SELECT运行时的值。

因此,让我们假设在您的示例中,我分别选择了一些数据A和值。现在假设我想更新(下面的语句只是一个例子):B12B

UPDATE TestClass SET B = '3' WHERE Id = 1;

但是,不要运行该语句(因为那里没有并发),让我们运行这个:

UPDATE TestClass SET B = '3' WHERE Id = 1 AND A = '1' AND B = '2';

该声明现在确保记录没有被任何人更改。

然而,目前看来 Subsonic 的 SimpleRepository 不支持任何类型的并发,所以这将是一个重大的失败。如果您正在寻找一个非常直接的存储库库,您可以在其中使用 POCO,我会推荐 Dapper。实际上,Stackoverflow 使用了 Dapper。它非常快,并且很容易让您在更新语句中构建并发,因为您发送参数化的 SQL 语句很简单。

  1. 这篇Stackoverflow 文章是一篇关于如何将 Dapper 用于所有 CRUD 操作的整体文章。
  2. 这篇Stackoverflow 文章展示了如何使用 Dapper 执行插入和更新。

注意:使用 Dapper,您实际上也可以做您想做的事情,因为您发送基本的 SQL 语句,但我不建议您不使用并发。

于 2012-09-12T11:19:04.470 回答
1

这种情况不要在DataObject上调用update方法,你基本上是在表明对象已经改变,需要在DB中更新。所以亚音速会生成一个查询

UPDATE TestClass SET A ='', B='', ModifiedOn = 'DateHere' WHERE PrimaryKey = ID

要仅更改属性 B,您需要手动构造 UPDATE 查询。看看Subsonic.Update课堂。
理想情况下,您不应该手动形成数据对象的新实例,如果这样做,请确保从Subsonic.Select查询返回的对象中复制值。
因此,即使您只更新一个属性的值,所有其他属性都将保存自己的 DB 值,而不是默认值,具体取决于属性的类型。

于 2012-09-12T11:20:04.407 回答