C# 使用多年后更新数据库

C# 使用多年后更新数据库,c#,sql,C#,Sql,编辑1:结尾的故事示例 几年前,我们创建表格是为了统计我们的包装盒中有多少产品。 有两个简单的表格: product ( code VARCHAR(16) PK, length INT, width INT, height INT ) box ( pkid INT IDENTITY(1,1), barcode varchar(18), product_code VARCHAR(16) FK, quantity INT ) 有两

编辑1:结尾的故事示例


几年前,我们创建表格是为了统计我们的包装盒中有多少产品。
有两个简单的表格:

product (
    code VARCHAR(16) PK,
    length INT,
    width INT,
    height INT
)

box (
    pkid INT IDENTITY(1,1),
    barcode varchar(18),
    product_code VARCHAR(16) FK,
    quantity INT
)
有两个相关的类:

public struct Product
{
    public string Code { get; set; }
    public int Length { get; set; }
    public int Width { get; set; }
    public int Heigth { get; set; }
}

public struct Box
{
    public int Id { get; set; }
    public string BarCode { get; set; }
    public Product Product { get; set; }
    public int Quantity { get; set; }
}

多年后,我们需要将多个不同的产品放在同一个盒子中,因此我们现在需要:

product (
    code VARCHAR(16) PK,
    length INT,
    width INT,
    height INT
)

-- box changed
box (
    pkid INT IDENTITY(1,1),
    barcode varchar(18)
)

-- stock created
stock (
    box_pkid INT M-PK FK,
    product_code VARCHAR(16) M-PK FK,
    quantity INT
)
这是:

public struct Product
{
    public string Code { get; set; }
    public int Length { get; set; }
    public int Width { get; set; }
    public int Heigth { get; set; }
}

public struct Box
{
    public int Id { get; set; }
    public string BarCode { get; set; }
    public Dictionary<Product, int> Content { get; set; } // <-- this changed
    public int Quantity { get; set; }
}
公共结构产品
{
公共字符串代码{get;set;}
公共整数长度{get;set;}
公共整数宽度{get;set;}
公共整数高度{get;set;}
}
公共结构盒
{
公共int Id{get;set;}
公共字符串条形码{get;set;}

公共字典内容{get;set;}/安全地更新遗留系统是一个典型的问题。我从你的帖子中猜测,没有一个很好的DB的安全开发副本,或者至少有一个是最新的,或者你已经有了一个应用程序

我以一种与系统无关的方式写了这篇文章,尽管您显然在使用MS SQL Server

关键是要谨慎行事,并确保在出现问题时,你永远不会100%陷入困境

  • 备份旧数据库。确保您知道如何在不破坏任何内容的情况下执行此操作。
  • 将备份还原到新位置
  • 制定测试计划(这可能是工作中最长的部分)
  • 对数据库的新副本进行更改(不要触摸活动副本)
  • 运行您的测试计划,以确保没有任何内容被破坏
  • 如果第5步显示了一些错误,您只需解决它们。一旦完成,您就有了可怕的部分。备份还原演练在这里至关重要

  • 对实时数据库进行备份(您以前的备份可能已过期。您希望备份尽可能新鲜,以减少数据丢失)
  • 运行备份还原演练,以100%确保您可以恢复
  • 将更改应用于实时数据库
  • 重新运行测试

  • 用许多数据库引擎将数据库恢复到单个事务是可能的。如果可能的话,请考虑使用步骤6。如何实现这将是一个独立的问题。

    你有很多挑战;我会把它们分成两个高级组。

    首先,如何在代码级别更改应用程序,其次,如何将数据从旧模式迁移到新模式

    如何更改代码? 第一个问题是:您能否100%确定您列出的类是访问和修改数据的唯一方式?是否存在触发器、存储过程、批处理作业或其他应用程序?我不知道有什么方法可以找到这一点,除了通过搜索数据库模式工件和代码库

    在“自己的”应用程序中,您有一个选择。扩展接口通常比修改接口更好。实际上,这意味着不必更改公共
    产品{get;set;}
    签名来处理字典,而是保留它,并添加
    公共字典内容{get;set;}
    -如果您可以保证旧方法仍然有效。这意味着有限地重新编写类的所有依赖项-您只需担心需要了解一个盒子中可能有多个产品的客户端

    这允许您遵循“许多小的更改,但现有代码仍能继续工作”的模型;您可以通过功能切换等来管理此模型。风险要低得多-因此这里的课程是“设计您的解决方案”

    在这种情况下,这似乎是不可能的,“set”方法可能还可以(您可以将其默认为“盒子中的一个产品”解决方案),但是“get”方法将无法优雅地处理一个框中包含多个产品的情况。如果是这样,则更改类,查找代码无法编译的所有实例,并遵循依赖关系链

    例如,在典型的MVC框架中,在这种情况下,您将更改模型;这将导致控制器报告一个编译错误。在解决该错误时,您几乎肯定会修改控制器方法的签名。这反过来会破坏视图。因此,您遵循该链;这样做意味着您的架构更改将成为一个错误《大爆炸,要么全有,要么全无》的发布。这对所有相关人员来说都是一种压力

    你如何释放你的变化? 这在很大程度上取决于您选择了两个选项中的哪一个。@gburton的回答涵盖了数据库步骤;这两个代码选项都需要这些步骤


    第二个挑战是发布软件的新版本;例如,如果是桌面客户端,则必须确保在数据库更改的同时更新所有客户端糟糕透了。如果是web应用程序,通常会简单一点-需要担心的客户端机器更少。

    具体来说,您担心什么?“确保数据完整性安全”"这是一个非常宽泛的话题……你说你是一名实习生。这项任务有潜在的风险,例如数据丢失、系统停机时间延长、错误的记帐等。有经验的人应该对此进行规划并负责。请将其提交给软件架构师。他/她应该负责这里的任何决策;这就是他/她做出决策的原因这是一大笔钱,你没有。如果它没有损坏,就不要修复它。你能展示完整的故事吗?
    有1个
    ID
    和1个
    barcode
    ,这意味着同一个条形码可能会出现很多次。这是一个错误吗?如果是的话,为什么你只需要表来存储一列,你可以使用
    索引
    来从<代码>框
    。所以你根本不必更改模式解决方案“不更改任何内容”不是我希望阅读的。我问这个问题是为了预测有一天我必须进行修改,不管是什么原因。如果我很了解你,你在应用方面的建议是