2

好的,这是场景。我认为这很常见,并且我在前世使用蛮力方法解决了它,但我认为必须有更好的方法。

给定一个有序的姓名列表,以及一个用户可以对列表重新排序、删除、编辑和添加姓名的 UI,您将如何更新存储在 SQL 数据库中的列表?

这是表定义:

CREATE TABLE [dbo].[AssyLines](
  [AssyLineID] [int] IDENTITY(1,1) NOT NULL,
  [ShortName] [varchar](16) NOT NULL,
  [LongName] [varchar](45) NOT NULL,
  [Seq] [tinyint] NOT NULL,
CONSTRAINT [PK_AssyLines] PRIMARY KEY CLUSTERED 

我想要做的是从表中读取所有条目并在 UI 中按 Seq 顺序显示它们。然后用户可以编辑 ShortName 或 LongName,重新排序列表,添加新条目或删除现有条目,然后将修改后的列表保存回数据库。

这是一个客户端-服务器应用程序,如果这有什么不同的话。WCF 服务处理数据库交互,客户端只是向服务发送和从服务发送记录数组。

我的蛮力方法包括锁定表,删除所有条目,然后将新记录重写到表中——当然,所有这些都在事务中,使用存储过程和表变量或临时表。粗鲁但有效,但我不禁觉得有一种相当标准的方法可以做到这一点,而无需在每次有人进行小幅编辑时对表格进行核对并重新创建它。

有任何想法吗?我目前正在处理的应用程序中有 4 或 5 个这样的列表。

谢谢,戴夫

4

3 回答 3

0

我不是 .NET 开发人员,但要做到这一点,另一种更优雅的方法是在桌面上设置 3 个侦听器;添加侦听器、更新侦听器和删除侦听器。侦听器将分别触发 INSERT、UPDATE 和 DELETE。

对列表进行排序对存储在数据库中的数据没有影响。

于 2011-02-11T17:15:12.617 回答
0

为什么不对每条记录(由 AssyLineID 标识,不应该更改)运行 UPDATE 查询,将其他列更新为用户指定的内容?无需删除任何内容,您可以通过跟踪用户更改的内容来减少数据库操作量。

如果您担心重新订购Seq零件,我认为这将适用:

if (newSeq < oldSeq)
{
    sql = "UPDATE AssyLines SET Seq = Seq + 1 WHERE Seq >= @seq AND Seq < @oldSeq AND AssyLineID <> @lineID";
}
else if (newSeq > oldSeq)
{
    sql = "UPDATE AssyLines SET Seq = Seq - 1 WHERE Seq <= @seq AND Seq > @oldSeq AND AssyLineID <> @lineID";
}

也许我不明白为什么你觉得你需要每次都用核武器攻击桌子。除了 Seq 部分之外,这听起来像是您的基本选择-修改-保存操作。

于 2011-02-11T17:18:32.567 回答
0

我将采用的方法是使用主键将更新、插入和删除与更改联系起来,并通过数据进行几次传递。

  1. 将数据库中的列表加载到 UI 中,并根据项目存储 ID。此外,存储一个“已更改”标志,该标志最初为每个项目设置为 false。
  2. 像这样对 UI 中的数据进行任何更改:
    • 通过添加数据来添加数据,将 ID(主键)设置为 -1,并将更改的标志设置为 true。
    • 通过编辑数据更新数据,将 changed 标志设置为 true。
    • 只需删除它们即可从数据中删除。
  3. 遍历列表中更改 flag=true 的每个项目并执行以下操作:
    • 如果 ID = -1,则使用 INSERT 添加新记录。
    • 如果 ID > -1,则根据您要使用 UPDATE 更新的记录更新与 ID 匹配的现有记录。
  4. 然后重新读取数据库中存在的所有记录的ID,遍历每一个并检查列表以查看它是否存在。如果不是,则使用 DELETE 将其从数据库中删除。

如果您有大量数据,第 4 步可能会变得非常缓慢。一种稍微不同的更有效的方法取决于是否可以在 UI 中将记录“标记”为已删除,并将其从视图中隐藏而不将其删除。然后,您可以将更改的标志替换为设置为“I”、“U”或“D”的状态,具体取决于它是插入、更新还是删除。然后你只需要一次通过数据。

于 2011-02-11T17:40:10.553 回答