EPR类企业管理系统

在我们现有系统基础上或全新开发,提供定制服务
为您的企业高效快速实施ERP,WMS,MES,CRM管理系统
全面管控物料仓库、销售业务、采购业务、仓库业务
生产过程、质量检验、组织架构、业务报表


定制
QQ:460-3528

开发
QQ群:3360-90194

源码
微信:136-3650-3721

如何:处理业务类及其属性的重命名和删除

开发XAF应用程序时,由于重构细节或更改的业务需求,可能需要重命名持久性类或属性。在添加新类或属性后,以调试模式启动的XAF应用程序会在数据库中自动创建所需的表和列(请参阅业务类与数据库表)话题)。但是,当重命名数据库中已经具有对应表的持久性类时,该类将被视为新类,并创建一个新表。结果,旧表保持未使用状态,并且重命名的类数据变得不可用。重命名数据库表中已经具有对应列的持久性属性时,也是如此。为新属性创建一个新列,而旧列保持未使用状态。在开发阶段,这些并不是大问题-您可以手动重命名所需的表/列,甚至创建新数据库。但是,如果您的应用程序已经分发给最终用户,并且他们具有包含生产数据的数据库,则此方法不适合。本主题描述了在更新XAF应用程序时自动处理数据库结构更改的方法,并避免手动更新所有最终用户数据库。提供了几种典型方案,您可以遵循其中一种,也可以将它们结合起来以处理更复杂的更改:

重点

当您直接连接到MS SQL Server时,某些ModuleUpdater类受保护的方法(如本主题中演示的RenameTableRenameColumn)适用,并且可能不适用于其他数据库引擎。如果在使用这些方法时遇到异常,则可以将适当的查询传递给ExecuteNonQueryCommandExecuteScalarCommandExecuteReader命令。

重命名持久属性

假设您拥有具有Office属性的Department类,并且需要将此属性重命名为Room。

[DefaultClassOptions ]
public class Department : BaseObject {
    // ...
    private string office;
    public string Office {
        get { return office; }
        set { SetPropertyValue(nameof(Office), ref office, value); }
    }
    // ...

需要以下步骤来重命名属性,并处理数据库和应用程序模型的更改。

这些步骤将在下面详细说明。

  • 重命名C#或VB源中的属性

    使用Visual Studio重构| 重命名...命令可查看您的解决方案源,并在使用该属性的任何位置重命名该属性。

    HowToHandleDbChanges1

    重建解决方案以确保它是可编译的,但不要运行该应用程序,以避免为新的属性名称创建新的表列。

  • 重命名XAFML和BO文件中的属性

    重构工具不会更新XAFML代码。使用“查找和替换”对话框浏览XAFML文件以重命名属性。在Visual Studio中,可以使用“编辑” |“创建”对话框。查找和替换| 快速替换菜单命令或CTRL-H快捷键。例如,如果您具有自定义的“部门详细信息视图”布局,或者在筛选条件中使用了“ Office”属性,则可能需要这样做。否则,定制将丢失。

    HowToHandleDbChanges11

  • 重命名保存重命名属性值的表列

    在更新数据库架构之前,应重命名存储Office属性值的数据库表中 的Office列。

    HowToHandleDbChanges5

    ModuleUpdater.UpdateDatabaseBeforeUpdateSchema方法的目的是将数据库架构更新之前更新应用程序数据库。我们将重写此方法以对数据库结构执行所需的更改。所述ModuleUpdater类公开RenameColumn保护方法,该方法将重命名数据库表中的所需的列中。以下代码段说明了如何将Department表中的Office列重命名为Room。

    public class Updater : ModuleUpdater {
        // ...
        public override void UpdateDatabaseBeforeUpdateSchema() {
            base.UpdateDatabaseBeforeUpdateSchema();
            if (CurrentDBVersion < new Version("1.1.0.0") 
                && CurrentDBVersion > new Version("0.0.0.0")) {
                RenameColumn("Department", "Office", "Room");
            }
         }
        // ...
    

    “ 1.1.0.0”字符串是引入更改的应用程序版本。因此,仅当数据库版本小于“ 1.1.0.0”时,该列才会重命名。需要检查数据库版本是否大于“ 0.0.0.0”,仅在数据库存在并且填充了数据时才进行更改(默认情况下,空数据库版本为“ 0.0.0.0”)。

    在此示例中实际执行的SQL命令是:

    执行sp_rename N'Department.Office',N'Room“','COLUMN'

    在执行之前,SQL命令文本将使用“ ExecuteNonQueryCommand:”前缀写入应用程序日志文件。如果在执行RenameColumn方法时发生错误,则还将记录异常文本。但是,在出现错误的情况下,应用程序的执行不会中断。您可以参考应用程序日志文件以进行调试。

  • 增加应用程序版本,运行应用程序,并确保属性名称已更改且数据可用。

您可以检查在数据库更新期间是否修改了列名称。如果您的数据库服务器是Microsoft SQL Server,请运行Microsoft SQL Management Studio并使用“对象资源管理器”导航到已修改的列。

HowToHandleDbChanges4

如果您使用其他数据库服务器,请使用适当的数据库工具来检查列名是否被实际修改。

删除永久属性

如果从应用程序代码中删除持久属性,则该属性在应用程序界面中将不可见。但是,相应的列仍将存在于应用程序数据库中。若要删除列,请使用ModuleUpdater类公开的DropColumn保护的方法。此方法删除指定表上的指定列。以下代码段说明了如何从“部门”表中删除“房间”列。

public class Updater : ModuleUpdater {
    // ...
    public override void UpdateDatabaseBeforeUpdateSchema() {
        base.UpdateDatabaseBeforeUpdateSchema();
        if (CurrentDBVersion < new Version("1.1.0.0"))
            && CurrentDBVersion > new Version("0.0.0.0")) {
            DropColumn("Department", "Room");
        }
    }
    // ...

“ 1.1.0.0”字符串是引入更改的应用程序版本。因此,仅当数据库版本小于“ 1.1.0.0”时,才会删除该列。当数据库为空或不存在时,需要检查以确定数据库版本是否大于然后是“ 0.0.0.0”才能处理方案。

在此示例中实际执行的SQL命令是:

ALTER TABLE dbo。部门DROP COLUMN [房间]

在执行之前,SQL命令文本将使用“ ExecuteNonQueryCommand:”前缀写入应用程序日志文件。如果在执行DropColumn方法时发生错误,则还将记录异常文本。但是,应用程序的执行不会中断。您可以参考应用程序日志文件以进行调试。

注意

删除属性会影响该属性以前可见的局部视图的布局。删除属性后,可能需要调整布局。

您可以检查是否在数据库更新期间删除了该列。如果您的数据库服务器是Microsoft SQL Server,请运行Microsoft SQL Management Studio并导航到“对象资源管理器”中的已修改表。如果您使用其他数据库服务器,请使用适当的数据库工具检查该列是否已被删除。

更改持久属性的数据类型

假设您拥有带有Description字符串属性的Department类。

public class Department : BaseObject {
    // ...
    private string description;
    public string Description {
        get { return description; }
        set { SetPropertyValue(nameof(Description), ref description, value); }
    }
    // ...

XPO中文本属性的默认大小为100个字符。例如,如果您的数据库服务器是Microsoft SQL Server 2005,则会为string属性创建一个具有nvarchar(100)数据类型的列。

HowToHandleDbChanges2

最初创建属性的列时,可以通过在属性的声明中添加SizeDbType属性来指定数据类型(请参阅如何增加持久对象的文本字段大小)。若要更改现有列的数据类型,请使用ModuleUpdater类公开的ExecuteNonQueryCommand受保护的方法。此方法执行指定的SQL语句。以下代码段说明了如何将Description列数据类型设置为nvarchar(200)。

public class Updater : ModuleUpdater {
    // ...
    public override void UpdateDatabaseBeforeUpdateSchema() {
        base.UpdateDatabaseBeforeUpdateSchema();
        if (CurrentDBVersion < new Version("1.1.0.0") 
            && CurrentDBVersion > new Version("0.0.0.0"))  {
            ExecuteNonQueryCommand(
                "alter table Department alter column Description nvarchar(200)", true);
        }
    }
    // ...

“ 1.1.0.0”字符串是引入更改的应用程序版本。因此,仅当数据库版本小于“ 1.1.0.0”时,数据类型才会更改。需要检查数据库版本是否大于“ 0.0.0.0”,才能仅在数据库存在并且填充了数据时进行更改(默认情况下,空数据库版本为“ 0.0.0.0”)。可用的数据类型取决于数据库服务器,因此请确保指定的数据类型有效。在执行之前,SQL命令文本将使用“ ExecuteNonQueryCommand:”前缀写入应用程序日志文件。如果在执行ExecuteNonQueryCommand时发生错误方法,也会记录异常文本。但是,应用程序的执行不会中断。您可以参考应用程序日志文件以进行调试。如果需要在发生错误时引发异常,请将ExecuteNonQueryCommand方法的第二个参数设置为false

注意

确保属性编辑器允许您输入所需大小的文本。在模型编辑器中,修改BOModel |的Size属性。部门| 描述节点,如有必要。此属性指定可以在属性编辑器中键入的最大字符数。

您可以检查数据类型在数据库更新期间是否已修改。如果您的数据库服务器是Microsoft SQL Server,请运行Microsoft SQL Management Studio并导航到“对象资源管理器”中的已修改列。

HowToHandleDbChanges3

如果您使用其他数据库服务器,请使用适当的数据库工具来检查数据类型是否被实际修改。

重命名持久性类

假设您有一个Department持久类,应将其重命名为Division。需要以下步骤来重命名类并处理所需的数据库和应用程序模型更改:

这些步骤将在下面详细说明。

  • 重命名C#或VB源中的类

    使用Visual Studio重构| 重命名...命令可查看您的解决方案源,并在使用该类的任何地方重命名该类。

    HowToHandleDbChanges6

    重建解决方案以确保其可编译,但不要运行该应用程序,以避免为新的类名创建新表。

  • 重命名XAFML和BO文件中的类

    重构工具不会更新XAFML代码。使用“查找和替换”对话框浏览XAFML文件的代码,以在使用该类的任何地方重命名该类。在Visual Studio中,可以使用“编辑” |“创建”对话框。查找和替换| 快速替换菜单命令或CTRL-H快捷键。

    HowToHandleDbChanges9

    注意

    列表视图和详细视图ID应该被修改。例如,“ Department_ListView” ID应该重命名为“ Division_ListView”。因此,请勿选中“匹配整个单词”选项。

  • 重命名包含重命名的类数据的数据库表,并更新XPObjectType表

    在更新数据库架构之前,应重命名数据库中 的Department表。

    HowToHandleDbChanges8

    自动创建并包含所有有效持久对象类型 的XPObjectType表也​​应进行修改。

    HowToHandleDbChanges7

    ModuleUpdater.UpdateDatabaseBeforeUpdateSchema方法的目的是将数据库架构更新之前更新应用程序数据库。我们将重写此方法以在数据库结构中执行所需的更改。该ModuleUpdater类公开RenameTableUpdateXPObjectType保护的方法。该RenameTable方法将重命名指定的表。第一个参数是旧名称,第二个参数是新名称。该UpdateXPObjectType方法更新XPObjectType桌子。此方法查找TypeName列值等于第一个参数的行。在此行中,它将TypeName列更改为第二个参数指定的值,并将AssemblyName列更改为第三个参数指定的值。以下代码段说明了如何将Department表重命名为Division并更新XPObjectType表。

    public class Updater : ModuleUpdater {
        // ...
        public override void UpdateDatabaseBeforeUpdateSchema() {
            base.UpdateDatabaseBeforeUpdateSchema();
            if (CurrentDBVersion < new Version("1.1.0.0") 
                && CurrentDBVersion > new Version("0.0.0.0")) {
                RenameTable("Department", "Division");
                UpdateXPObjectType(
                    "MySolution.Module.Department", "MySolution.Module.Division", "MySolution.Module");
            }
        }
        // ...
    

    “ 1.1.0.0”字符串是引入更改的应用程序版本。因此,仅当数据库版本小于“ 1.1.0.0”时,才会删除该列。仅当数据库存在并且被数据填充时,才需要检查数据库版本是否大于“ 0.0.0.0”。

    在此示例中实际执行的SQL命令是:

    sp_rename'部门','部门','对象'

    更新XPObjectType设置TypeName ='MySolution.Module.Division',AssemblyName ='MySolution.Module'

    其中TypeName ='MySolution.Module'

    在执行之前,SQL命令文本将以“ ExecuteNonQueryCommand:”为前缀写入应用程序日志文件。如果在执行RenameTableUpdateXPObjectType方法时发生错误,则还将记录异常文本。但是,在发生错误的情况下,应用程序的执行不会中断。您可以参考应用程序日志文件以进行调试。

增加应用程序版本,运行应用程序,并确保更改了类名,并且数据可用。

您可以检查在数据库更新期间是否修改了类的表名。如果您的数据库服务器是Microsoft SQL Server,请运行Microsoft SQL Management Studio并导航到“对象资源管理器”中的已修改表。

HowToHandleDbChanges8_1

如果您使用其他数据库服务器,请使用适当的数据库工具来检查表名是否被实际修改。

重命名多对多关系中的持久性班级参与者

假设您拥有Department和Position类,并且存在Department-Position多对多关系。必须将部门重命名为部门

[DefaultClassOptions ]
public class Department : BaseObject {
    // ...
    [Association("Departments-Positions")]
    public XPCollection<Position> Positions {
        get { return GetCollection<Position>(nameof(Positions)); }
    }
    // ...
}
[DefaultClassOptions]
public class Position : BaseObject {
    // ...
    [Association("Departments-Positions")]
    public XPCollection<Department> Departments {
        get { return GetCollection<Department>(nameof(Departments)); }
    }
    // ...
}

在这种情况下,需要“重命名持久性类”部分中描述的所有步骤。但是,还有两个附加步骤。

  • Position.Departments属性重命名为Divisions并修改此属性的getter中使用的属性名称。将“部门位置”关联名称更改为“部门位置”。
  • 需要在存储关系信息的同时修改PositionPositions_DepartmentDepartments数据库表-重命名Departments列和表本身。

    HowToHandleDbChanges12

    要执行重命名,请将以下代码添加到UpdateDatabaseBeforeUpdateSchema方法中。

    if (TableExists("PositionPositions_DepartmentDepartments")) {
        RenameColumn("PositionPositions_DepartmentDepartments", "Departments", "Divisions");
        RenameTable("PositionPositions_DepartmentDepartments", "PositionPositions_DivisionDivisions");
    }
    

重命名在分析中用作数据类型的持久性类

如果在您的应用程序中使用了Analysis业务类,则可能需要修改最终用户数据库中的Analysis表。这是必需的,因为最终用户可以使Analysis对象的DataType属性指向重命名的类。因此,在执行“重命名持久性类”部分中描述的步骤之后,将以下代码添加到UpdateDatabaseBeforeUpdateSchema方法中。

ExecuteNonQueryCommand(
    "update Analysis set ObjectTypeName = 'MySolution.Module.Division' "   
    "where ObjectTypeName = 'MySolution.Module.Department'", true);

重命名在报告中用作数据类型的持久性类

如果将Reports V2模块添加到您的应用程序,则需要修改报告的数据。这是必要的,因为最终用户可能具有IReportDataV2.DataType属性指向重命名的类的报表。因此,在执行“重命名持久性类”部分中描述的步骤之后,将以下代码添加到UpdateDatabaseBeforeUpdateSchema方法中。

using DevExpress.ExpressApp.ReportsV2;
//...
ReportDataProvider.MassUpdateDataType<ReportDataV2>(
    ObjectSpace, "MySolution.Module.Department", typeof(Division));

在上面的代码中,使用ReportDataProvider.MassUpdateDataType <T>方法代替ExecuteNonQueryCommand

删除持久性类

如果从应用程序代码中删除持久类,则该类在应用程序界面中将不可见。但是,相应的表仍将存在于应用程序数据库中。若要删除表,请使用ModuleUpdater类公开的DropTable受保护的方法。此方法删除指定的表。以下代码段说明了如何删除“除法”表。

public class Updater : ModuleUpdater {
    // ...
    public override void UpdateDatabaseBeforeUpdateSchema() {
        base.UpdateDatabaseBeforeUpdateSchema();
        if (CurrentDBVersion < new Version("1.1.0.0")
            && CurrentDBVersion > new Version("0.0.0.0")) {
            DropTable("Division", true);
            DeleteObjectType("MySolution.Module.Division");
        }
    }
    // ...

“ 1.1.0.0”字符串是引入更改的应用程序版本。因此,仅当数据库版本小于“ 1.1.0.0”时,才会删除该表。需要检查数据库版本是否大于“ 0.0.0.0”,才能仅在数据库存在并且填充了数据时进行更改(默认情况下,空数据库版本为“ 0.0.0.0”)。

在此示例中实际执行的SQL命令是:

放表部

从XPObjectType中删除,其中TypeName ='MySolution.Module.Division'

在执行之前,将使用“ ExecuteNonQueryCommand:”前缀将SQL命令文本写入应用程序日志文件。如果在执行DropTableDeleteObjectType方法时发生错误,则还将记录异常文本。但是,应用程序的执行不会中断。您可以参考应用程序日志文件以进行调试。如果删除表时发生错误,如果需要引发异常,则将DropTable方法的第二个参数设置为false

您可以检查是否在数据库更新期间删除了该表。如果您的数据库服务器是Microsoft SQL Server,请运行Microsoft SQL Management Studio并导航到“对象资源管理器”中的应用程序数据库表列表。如果您使用其他数据库服务器,请使用适当的数据库工具来检查该表是否已被删除。

相关文章

转载保留此链接,注明出处