Я пытаюсь создать собственный анализ кода для проектов баз данных. У меня есть пара утверждений, написанных для таблиц, которые в настоящее время работают нормально. Однако моя первая проверка для просмотров не работает. При отладке правил он фактически вступает в правило один раз и только один раз. В то время ruleExecutionContext.ModelElement имеет значение NULL. Я рассмотрел другой класс, который будет использоваться, помимо класса типа представления, но это, по-видимому, правильный. В настоящее время я использую эту версию SSDT: SSDT_14.0.61021.0_RU вместе с Visual Studio 2015. Я полностью потеряю, почему работают тесты таблицы, но взглядов нет.Анализ кода Проверка просмотров в DACPAC с использованием DacFX
[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(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;
}
}
Yep, model scope действительно подходит только тогда, когда вам нужно сделать один проход (например, если ваш проект проверяет все объекты и флаги на коррелированные проблемы. Вы можете запросить модель для типов элементов (например, вызов model.GetObjects()), но лучше всего использовать область применения элементов, если вы хотите, чтобы поэтапный анализ –