如何动态删除 nopCommerce 插件表?

How can I DROP nopCommerce plugin tables dynamically?

I recently developed a fairly large plugin that saw a lot of changes throughout. I asked myself this question after having to manually drop tables I forgot to include in the Uninstall() method.

我正在构建一个 nopCommerce 插件,我想让我的 PluginNameObjectContext.Uninstall() 方法更加灵活。

我关注了Alex Wolf's tutorial*,目前看起来像:

this.DropPluginTable("firstTable");
this.DropPluginTable("secondTable");
....
this.DropPluginTable("nthTable");

有很多地方需要在代码中反映对插件数据访问层的更改。当我在插件的域中添加或删除 类 时,我一直忘记更新此方法,这会导致错误,然后进行一些清理。

如何使这个方法更动态,并减轻整个开发过程中的维护负担?


* 该视频系列适用于 Nop 3.5,技术上比当前版本落后 0.2,但如果您是 nopCommerce 开发的新手,它绝对是无价的。他的 blog 也有一些非常有用的帖子。

感谢 MVC 和 NopCommerce 倡导的 Convention over Configuration 原则,我们可以利用一致的命名。

配置数据访问时遵守命名约定,特别是您的 EntityTypeConfiguration<T Entity> 映射 类。将所有 ToTable() 方法设置为以插件名称开头,如下所示:

ToTable("PluginName_InterestingStuff");

HasKey(k => k.Id);
Property(p => p.Puppies);
...

这样,ObjectContext class 中的 Install() 方法将生成 SQL 以您的插件名称开头的表:

dbo.PluginName_Foo
dbo.PluginName_Bar

如果您正确配置了 code-first classes,您可能会有一些外键。按照设计,这些也将遵循命名约定,它们的名称将以您的插件名称开头。

通过在您的应用程序数据库中创建一个存储过程来利用这一点,该存储过程将删除所有包含 @YourPluginName 的外键和表。下面是 SQL 将执行此操作的脚本。

/** 
    This is a convenience proc to uninstall a nop commerce plugin "dynamically"
    This proc DROPs all foreign keys, and then all tables, 
    whose name contains the @YourPluginName param.
    If naming conventions are followed, 
    there will be no side effects, but USE WITH CAUTION! 

    Please do a SELECT on sys.tables 
    with your Param before running this. 
**/

CREATE PROC sp_UninstallPluginTables
(
    @YourPluginName VARCHAR(250) /*This will typically be the nopcommerce plugin name */
)
/*----------------------------------FOREIGN KEYS---------------------------------------*/
declare CollectFkNames cursor for
  SELECT 'ALTER TABLE ' + T.NAME + ' DROP CONSTRAINT ' + FK.NAME
  FROM sys.foreign_keys FK
    INNER JOIN sys.tables T ON T.object_id = FK.parent_object_id
  WHERE FK.NAME LIKE @YourPluginName + '_%'
  ORDER BY T.Name DESC

declare @DropForeignKeysCmd varchar(max)

open CollectFkNames
    fetch next from CollectFkNames 
      into @DropForeignKeysCmd
    while @@FETCH_STATUS=0
    begin
      exec(@DropForeignKeysCmd)
      fetch next from CollectFkNames 
      into @DropForeignKeysCmd
    end
close CollectFkNames
deallocate CollectFkNames
GO

/*-------------------------------------TABLES------------------------------------------*/
declare CollectTableNames cursor for
  SELECT 'DROP TABLE ' + T.NAME
  FROM sys.tables T 
  WHERE T.NAME LIKE @YourPluginName + '_%'
  ORDER BY T.Name DESC

declare @DropTablesCmd varchar(max)

open CollectTableNames
    fetch next from CollectTableNames 
      into @DropTablesCmd
    while @@FETCH_STATUS=0
    begin
      exec(@DropTablesCmd)
      fetch next from CollectTableNames 
      into @DropTablesCmd
    end
close CollectTableNames
deallocate CollectTableNames
GO