使用 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 检查解决了这个问题。
我正在尝试为数据库项目创建自定义代码分析。我为 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 检查解决了这个问题。