C# 使用DacFX对DACPAC中的视图进行代码分析验证
我正在尝试为数据库项目创建自定义代码分析。我为目前运行良好的表编写了一些验证。然而,我对视图的第一次验证似乎不起作用。在调试规则时,它实际上会破译规则一次,而且只有一次。此时ruleExecutionContext.ModelElement为空。除了视图类型类之外,我已经四处寻找了另一个要使用的类,但它似乎是正确的。我目前正在使用这个版本的SSDT:SSDT_14.0.61021.0_EN以及Visual Studio 2015。我完全不知道为什么表测试可以工作,但是视图不能C# 使用DacFX对DACPAC中的视图进行代码分析验证,c#,database-project,dacpac,C#,Database Project,Dacpac,我正在尝试为数据库项目创建自定义代码分析。我为目前运行良好的表编写了一些验证。然而,我对视图的第一次验证似乎不起作用。在调试规则时,它实际上会破译规则一次,而且只有一次。此时ruleExecutionContext.ModelElement为空。除了视图类型类之外,我已经四处寻找了另一个要使用的类,但它似乎是正确的。我目前正在使用这个版本的SSDT:SSDT_14.0.61021.0_EN以及Visual Studio 2015。我完全不知道为什么表测试可以工作,但是视图不能 [ExportCo
[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;
}
}
[ExportCodeAnalysisRule(NestedViewRule.RuleId,
NestedViewRule.RuleDisplayName,
Description=NestedViewRule.RuleDisplayName,
类别=常数。性能,
RuleScope=SqlRuleScope.Model)]
公共密封类NestedViewRule:SqlCodeAnalysisRule
{
公共常量字符串RuleId=Constants.RuleNameSpace+“SRP0001”;
public const string RuleDisplayName=“视图不应将其他视图用作数据源”;
public const string Message=“视图{0}使用视图{1}作为数据源。这对性能有负面影响。”;
公共嵌套视图规则()
{
SupportedElementTypes=new[]{ModelSchema.View};//View.TypeClass,两者似乎都不起作用
}
公共重写IList分析(SqlRuleExecutionContext ruleExecutionContext)
{
列表问题=新列表();
TSqlObject sqlObj=ruleExecutionContext.ModelElement;
if(sqlObj!=null)
{
foreach(sqlObj.GetReferenced(DacQueryScopes.All)中的var子级,其中(x=>x.ObjectType==View.TypeClass))
{
string msg=string.Format(消息,RuleUtils.GetElementName(ruleExecutionContext,sqlObj),RuleUtils.GetElementName(ruleExecutionContext,child));
添加(新的SqlRuleProblem(msg,sqlObj)/*{Severity=SqlRuleProblemSeverity.Error}*/);
}
}
退货问题;
}
}
以下是我目前的工作表规则之一,以防有人感兴趣:
[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;
}
}
[ExportCodeAnalysisRule(TableHasPrimaryKeyRule.RuleId,
TableHasPrimaryKeyRule.RuleDisplayName,
Description=TableHasPrimaryKeyRule.RuleDisplayName,
类别=常数。最佳实践,
RuleScope=SqlRuleScope.Element)]
公共密封类TableHasPrimaryKeyRule:SqlCodeAnalysisRule
{
公共常量字符串RuleId=Constants.RuleNameSpace+“SRB0002”;
public const string RuleDisplayName=“表应具有主键。”;
public const string Message=“表{0}没有主键。”;
公共表hasPrimaryKeyRule()
{
SupportedElementTypes=new[]{ModelSchema.Table};
}
公共重写IList分析(SqlRuleExecutionContext ruleExecutionContext)
{
列表问题=新列表();
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(消息,RuleUtils.GetElementName(ruleExecutionContext,sqlObj));
添加(新的SqlRuleProblem(msg,sqlObj));
}
}
退货问题;
}
}
好的,很抱歉,但是在我发布它之后,我注意到我正在使用RuleScope=SqlRuleScope.Model进行视图检查,使用元素进行表检查。然后我推断,这迫使视图注册的访问者模式被忽略,模型被一次性传递给我
使用RuleScope=SqlRuleScope.Element更改属性以匹配表检查,修复了该问题。Yep,模型范围实际上仅适用于需要执行单个过程的情况(例如,如果您的设计扫描了相关问题的所有对象和标志。您可以查询模型中的元素类型(例如model.GetObjects()调用)但是,如果需要逐个元素的分析,最好使用元素范围