使用 SMO 收集依赖项时忽略触发器

Ignore triggers when gathering dependencies with SMO

我有一个系统可以在两个具有相同模式的数据库之间传输数据(用于开发目的)。

SMO dependency walker 除了触发器外工作得很好。如果我得到一个依赖列表,我不关心触发器是否引入了对另一个 table 的依赖,因为触发器不会在传输期间执行。如果有循环依赖就特别烦人。

我想知道是否有一种方法可以忽略依赖遍历步骤中的触发器。我尝试了一些方法,但没有成功:

这是我现在的代码:

var tablesToLoad = scripter.WalkDependencies(new DependencyWalker(server).DiscoverDependencies(filteredTables, DependencyType.Parents))
                           .Where(n => n.Urn.Type != "UnresolvedEntity")
                           .Select(n => server.GetSmoObject(n.Urn))
                           .OfType<Table>()
                           .ToArray();

变量 filteredTables 包含我要用于传输数据的 table 列表。结果是所有 tables,按照它们的依赖顺序,需要被转移,包括 tables 之间的依赖关系(包括需要拉入的其他 tables 以保持失败的外键关系)。

编辑:我想重申,问题不在于触发器是否正在执行。问题是 SMO 在确定加载 tables 的依赖顺序时会查看触发器。因此,如果触发器引用另一个 table,无论引用 table 的语句是否会在触发器中实际执行,该引用都会被视为依赖项解析。我根本不希望触发器用于依赖项解析。如何让 SMO 忽略触发器而不必将它们从数据库中删除?这是我的问题。

您可以创建 2 个 SQL 服务器存储过程,一个用于禁用触发器,另一个用于启用触发器。在加载 table 之前,使用 SqlCommand class 调用禁用触发器存储过程,当 table 加载完成时,使用 SQLCommand 执行启用触发器程序。

希望对您有所帮助!

看起来实现此目的的唯一方法是删除触发器,然后在依赖遍历器完成后重新添加它们。

首先,获取触发器列表并删除它们 --

var triggers = database.Triggers;
foreach (var trigger in triggers)
{
    trigger.Drop();
}

构建依赖树 --

var tablesToLoad = scripter.WalkDependencies(new DependencyWalker(server).DiscoverDependencies(filteredTables, DependencyType.Parents))
                           .Where(n => n.Urn.Type != "UnresolvedEntity")
                           .Select(n => server.GetSmoObject(n.Urn))
                           .OfType<Table>()
                           .ToArray();

重新创建触发器 --

foreach (var trigger in triggers)
{
    trigger.Create();
}