使用 DacFX 对 DACPAC 中的视图进行代码分析验证

Code Analysis Validation of Views in DACPAC using DacFX

我正在尝试为数据库项目创建自定义代码分析。我为 tables 编写了一些验证,目前运行良好。但是,我对视图的第一次验证似乎不起作用。在调试规则的时候,它实际上会一次且仅一次地打破规则。那时 ruleExecutionContext.ModelElement 为空。除了视图类型 class 之外,我还四处寻找另一个 class 来使用,但这似乎是正确的使用方法。我目前正在使用此版本的 SSDT:SSDT_14.0.61021.0_EN 以及 Visual Studio 2015。我完全不知道为什么 table 测试有效,但是观点没有。

[ExportCodeAnalysisRule(NestedViewRule.RuleId,
    NestedViewRule.RuleDisplayName,
    Description = NestedViewRule.RuleDisplayName,
    Category = Constants.Performance,
    RuleScope = SqlRuleScope.Model)]
public sealed class NestedViewRule : SqlCodeAnalysisRule
{
    public const string RuleId = Constants.RuleNameSpace + "SRP0001";
    public const string RuleDisplayName = "Views should not use other views as a data source";
    public const string Message = "View {0} uses view {1} as a datasource. This has a negative impact upon performance.";

    public NestedViewRule()
    {
        SupportedElementTypes = new[] { ModelSchema.View }; // View.TypeClass, neither seems to work
    }

    public override IList<SqlRuleProblem> Analyze(SqlRuleExecutionContext ruleExecutionContext)
    {
        List<SqlRuleProblem> problems = new List<SqlRuleProblem>();
        TSqlObject sqlObj = ruleExecutionContext.ModelElement;
        if (sqlObj != null)
        {
            foreach (var child in sqlObj.GetReferenced(DacQueryScopes.All).Where(x => x.ObjectType == View.TypeClass))
            {
                string msg = string.Format(Message, RuleUtils.GetElementName(ruleExecutionContext, sqlObj), RuleUtils.GetElementName(ruleExecutionContext, child));
                problems.Add(new SqlRuleProblem(msg, sqlObj) /*{ Severity = SqlRuleProblemSeverity.Error } */);
            }
        }

        return problems;
    }
}

这是我目前正在使用的 table 规则之一,以防有人感兴趣:

[ExportCodeAnalysisRule(TableHasPrimaryKeyRule.RuleId,
    TableHasPrimaryKeyRule.RuleDisplayName,
    Description = TableHasPrimaryKeyRule.RuleDisplayName,
    Category = Constants.BestPractice,
    RuleScope = SqlRuleScope.Element)]
public sealed class TableHasPrimaryKeyRule : SqlCodeAnalysisRule
{
    public const string RuleId = Constants.RuleNameSpace + "SRB0002";
    public const string RuleDisplayName = "Tables should have a primary key.";
    public const string Message = "Table {0} does not have a primary key.";

    public TableHasPrimaryKeyRule()
    {
        SupportedElementTypes = new[] { ModelSchema.Table };
    }

    public override IList<SqlRuleProblem> Analyze(SqlRuleExecutionContext ruleExecutionContext)
    {
        List<SqlRuleProblem> problems = new List<SqlRuleProblem>();
        TSqlObject sqlObj = ruleExecutionContext.ModelElement;
        if (sqlObj != null)
        {
            var child = sqlObj.GetChildren(DacQueryScopes.All).FirstOrDefault(x => x.ObjectType == PrimaryKeyConstraint.TypeClass);
            if (child == null)
            {
                string msg = string.Format(Message, RuleUtils.GetElementName(ruleExecutionContext, sqlObj));
                problems.Add(new SqlRuleProblem(msg, sqlObj));
            }
        }

        return problems;
    }
}

好的,我很抱歉,但在发布之后我注意到我正在使用 RuleScope = SqlRuleScope.Model 进行视图检查,并使用 Element 进行表格检查。然后我推断这是强制忽略视图注册的访问者模式,并将模型一次性传递给我。

使用 RuleScope = SqlRuleScope.Element 更改属性以匹配 table 检查解决了这个问题。