Skapa anpassade kodanalysregler
gäller för:SQL Server
Azure SQL Database
Azure SQL Managed Instance
SQL-databas i Microsoft Fabric
Den här genomgången visar de steg som används för att skapa en SQL Server-kodanalysregel. Regeln som skapas i den här genomgången används för att undvika WAITFOR DELAY
-instruktioner i lagrade procedurer, utlösare och funktioner.
I den här genomgången skapar du en anpassad regel för Transact-SQL statisk kodanalys med hjälp av följande steg:
- Skapa ett klassbiblioteksprojekt, aktivera signering för projektet och lägg till nödvändiga referenser.
- Skapa två C#-hjälpklasser.
- Skapa en anpassad C#-regelklass.
- Skapa klassbiblioteksprojektet.
- Installera och testa den nya kodanalysregeln.
Förutom visual studioinstruktionerna (SQL Server Data Tools) fokuserar guiden på SQL-projekt i SDK-stil.
Förutsättningar
Du behöver följande komponenter för att slutföra den här genomgången:
- En version av Visual Studio installerad, som innehåller SQL Server Data Tools, och stöder C# .NET Framework-utveckling.
- Ett SQL Server-projekt som innehåller SQL Server-objekt.
- En instans av SQL Server som du kan distribuera ett databasprojekt till.
Den här genomgången är avsedd för användare som redan är bekanta med SQL Server-funktionerna i SQL Server Data Tools. Du bör känna till Visual Studio-begrepp, till exempel hur du skapar ett klassbibliotek, lägger till NuGet-paket och hur du använder kodredigeraren för att lägga till kod i en klass.
Not
På grund av förhandsversionsbegränsningarna i SQL Server Data Tools i SDK-stil krävs flera Visual Studio-installationer för att slutföra den här genomgången. Den första installationen krävs för att skapa klassbiblioteksprojektet. Den andra installationen krävs för att skapa SQL-databasprojektet i SDK-format.
- .NET 8 SDK
- Visual Studio 2022 Community, Professional eller Enterprise
- SQL Server Data Tools, SDK-format (förhandsversion) installerat i Visual Studio 2022
- En version av Visual Studio installerad som stöder C# .NET-utveckling.
- Ett SQL Server-projekt som innehåller SQL Server-objekt.
Den här genomgången är avsedd för användare som redan är bekanta med SQL Server-funktionerna i SQL Server Data Tools. Du bör känna till Visual Studio-begrepp, till exempel hur du skapar ett klassbibliotek, lägger till NuGet-paket och hur du använder kodredigeraren för att lägga till kod i en klass.
- En version av Visual Studio Code installerad, som innehåller SQL Database Projects-tillägget.
- Ett SQL-databasprojekt som innehåller SQL-objekt.
- .NET 8 SDK
- Rekommenderas: C# Dev Kit-tillägg för VS Code
Den här genomgången är avsedd för användare som redan är bekanta med SQL Database Projects-tillägget i Visual Studio Code. Du bör känna till utvecklingsbegrepp, till exempel hur du skapar ett klassbibliotek, lägger till paket och hur du använder kodredigeraren för att redigera kod.
- En textredigerare, till exempel filredigeraren i Visual Studio Code.
- Ett SQL-databasprojekt som innehåller SQL-objekt.
- .NET 8 SDK
Den här genomgången är avsedd för användare som redan är bekanta med SQL-projekt. Du bör känna till utvecklingsbegrepp, till exempel hur du skapar ett klassbibliotek, lägger till paket och hur du använder kodredigeraren för att redigera kod.
Steg 1: Skapa ett klassbiblioteksprojekt
Skapa först ett klassbibliotek. Så här skapar du ett klassbiblioteksprojekt:
Skapa ett C#-klassbiblioteksprojekt (.NET Framework) med namnet
SampleRules
.Byt namn på filen
Class1.cs
tillAvoidWaitForDelayRule.cs
.Högerklicka på projektnoden i Solution Explorer och välj sedan Lägg till och sedan Referens.
Välj
System.ComponentModel.Composition
på fliken Sammansättningar\Ramverk.Högerklicka på projektnoden i Solution Explorer och välj sedan Hantera NuGet-paket. Leta upp och installera
Microsoft.SqlServer.DacFx
NuGet-paketet. Den valda versionen måste vara162.x.x
(till exempel162.2.111
) med Visual Studio 2022.
Lägg sedan till stödklasser som ska användas av regeln.
Skapa först ett klassbibliotek. Så här skapar du ett klassbiblioteksprojekt:
Skapa ett C#-klassbiblioteksprojekt (.NET Framework) med namnet
SampleRules
.Byt namn på filen
Class1.cs
tillAvoidWaitForDelayRule.cs
.Högerklicka på projektnoden i Solution Explorer och välj sedan Lägg till och sedan Referens.
Välj
System.ComponentModel.Composition
på fliken Sammansättningar\Ramverk.Högerklicka på projektnoden i Solution Explorer och välj sedan Hantera NuGet-paket. Leta upp och installera
Microsoft.SqlServer.DacFx
NuGet-paketet. Den valda versionen måste vara162.x.x
(till exempel162.2.111
) med Visual Studio 2022.
Lägg sedan till stödklasser som ska användas av regeln.
Starta Visual Studio Code och öppna mappen där du vill skapa projektet.
Öppna ett Terminal-fönster i Visual Studio Code genom att välja menyn Visa och sedan Terminal.
I Terminalanger du följande kommandon för att skapa en ny lösning och ett nytt projekt:
dotnet new sln dotnet new classlib -n SampleRules -o SampleRules dotnet sln add SampleRules/SampleRules.csproj
Ändra till katalogen
SampleRules
:cd SampleRules
Lägg till det nödvändiga NuGet-paketet:
dotnet add package Microsoft.SqlServer.DacFx
Lägg sedan till stödklasser som ska användas av regeln.
Öppna en kommandotolk eller ett terminalfönster och navigera till mappen där du vill skapa projektet.
I Terminalanger du följande kommandon för att skapa en ny lösning och ett nytt projekt:
dotnet new sln dotnet new classlib -n SampleRules -o SampleRules dotnet sln add SampleRules/SampleRules.csproj
Ändra till katalogen
SampleRules
:cd SampleRules
Lägg till det nödvändiga NuGet-paketet:
dotnet add package Microsoft.SqlServer.DacFx
Steg 2: Skapa anpassade regelhjälpklasser
Innan du skapar klassen för själva regeln lägger du till en besöksklass och en attributklass i projektet. Dessa klasser kan vara användbara för att skapa fler anpassade regler.
Steg 2.1: Definiera klassen WaitForDelayVisitor
Den första klassen som du måste definiera är klassen WaitForDelayVisitor
, härledd från TSqlConcreteFragmentVisitor. Den här klassen ger åtkomst till WAITFOR DELAY
-instruktioner i modellen. Besökarklasser använder ScriptDom API:er som tillhandahålls av SQL Server. I det här API:et visas Transact-SQL kod som ett abstrakt syntaxträd (AST) och besökarklasser kan vara användbara när du vill hitta specifika syntaxobjekt som WAITFOR DELAY
-instruktioner. Dessa instruktioner kan vara svåra att hitta med hjälp av objektmodellen eftersom de inte är kopplade till en specifik objektegenskap eller relation, men du kan hitta dem med hjälp av besöksmönstret och ScriptDom API.
I Solution Explorerväljer du projektet
SampleRules
.På menyn Project väljer du Lägg till klass. Dialogrutan Lägg till nytt objekt visas. I textrutan Namn skriver du
WaitForDelayVisitor.cs
och väljer sedan knappen Lägg till. FilenWaitForDelayVisitor.cs
läggs till i projektet i Solution Explorer.
I Solution Explorerväljer du projektet
SampleRules
.På menyn Project väljer du Lägg till klass. Dialogrutan Lägg till nytt objekt visas. I textrutan Namn skriver du
WaitForDelayVisitor.cs
och väljer sedan knappen Lägg till. FilenWaitForDelayVisitor.cs
läggs till i projektet i Solution Explorer.
Öppna vyn Explorer i Visual Studio Code.
Skapa en ny fil med namnet
WaitForDelayVisitor.cs
i mappenSampleRules
.
- Gå till katalogen
SampleRules
. - Skapa en ny fil med namnet
WaitForDelayVisitor.cs
.
Öppna filen
WaitForDelayVisitor.cs
och uppdatera innehållet så att det matchar följande kod:using System.Collections.Generic; using Microsoft.SqlServer.TransactSql.ScriptDom; namespace SampleRules { class WaitForDelayVisitor {} }
I klassdeklarationen ändrar du åtkomstmodifieraren till intern och härleder klassen från
TSqlConcreteFragmentVisitor
:internal class WaitForDelayVisitor : TSqlConcreteFragmentVisitor {}
Lägg till följande kod för att definiera variabeln Listmedlem:
public IList<WaitForStatement> WaitForDelayStatements { get; private set; }
Definiera klasskonstruktorn genom att lägga till följande kod:
public WaitForDelayVisitor() { WaitForDelayStatements = new List<WaitForStatement>(); }
Åsidosätt metoden
ExplicitVisit
genom att lägga till följande kod:public override void ExplicitVisit(WaitForStatement node) { // We are only interested in WAITFOR DELAY occurrences if (node.WaitForOption == WaitForOption.Delay) WaitForDelayStatements.Add(node); }
Den här metoden besöker
WAITFOR
-uttrycken i modellen och lägger till instruktioner som har detDELAY
alternativet som anges i listan överWAITFOR DELAY
-instruktioner. Nyckelklassen som refereras är WaitForStatement.På menyn Arkiv väljer du Spara.
Steg 2.2: Lägg till en resursfil och tre resurssträngar
Lägg sedan till en resursfil som definierar regelnamnet, regelbeskrivningen och den kategori där regeln ska visas i regelkonfigurationsgränssnittet.
I Solution Explorerväljer du projektet
SampleRules
. På menyn Project väljer du Lägg till och sedan Nytt objekt. Dialogrutan Lägg till nytt objekt visas.I listan över installerade mallarväljer du Allmänt. I informationsfönstret väljer du Resursfil.
I Namnskriver du
RuleResources.resx
. Resursredigeraren visas utan att några resurser har definierats.Definiera fyra resurssträngar på följande sätt:
Namn Värde AvoidWaitForDelay_ProblemDescription
WAITFOR DELAY statement was found in {0}.
AvoidWaitForDelay_RuleName
Avoid using WaitFor Delay statements in stored procedures, functions and triggers.
CategorySamples
SamplesCategory
CannotCreateResourceManager
Can't create ResourceManager for {0} from {1}.
På menyn Arkiv väljer du Spara RuleResources.resx.
I Solution Explorerväljer du projektet
SampleRules
. På menyn Project väljer du Lägg till och sedan Nytt objekt. Dialogrutan Lägg till nytt objekt visas.I listan över installerade mallarväljer du Allmänt. I informationsfönstret väljer du Resursfil.
I Namnskriver du
RuleResources.resx
. Resursredigeraren visas utan att några resurser har definierats.Definiera fyra resurssträngar på följande sätt:
Namn Värde AvoidWaitForDelay_ProblemDescription
WAITFOR DELAY statement was found in {0}.
AvoidWaitForDelay_RuleName
Avoid using WaitFor Delay statements in stored procedures, functions and triggers.
CategorySamples
SamplesCategory
CannotCreateResourceManager
Can't create ResourceManager for {0} from {1}.
På menyn Arkiv väljer du Spara RuleResources.resx.
I katalogen
SampleRules
skapar du en ny fil med namnetRuleResources.resx
.Öppna filen
RuleResources.resx
och lägg till följande kod:<?xml version="1.0" encoding="utf-8"?> <root> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:element name="root" msdata:IsDataSet="true"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="metadata"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" /> </xsd:sequence> <xsd:attribute name="name" use="required" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" /> <xsd:attribute ref="xml:space" /> </xsd:complexType> </xsd:element> <xsd:element name="assembly"> <xsd:complexType> <xsd:attribute name="alias" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" /> </xsd:complexType> </xsd:element> <xsd:element name="data"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> <xsd:attribute ref="xml:space" /> </xsd:complexType> </xsd:element> <xsd:element name="resheader"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" /> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:schema> <resheader name="resmimetype"> <value>text/microsoft-resx</value> </resheader> <resheader name="version"> <value>2.0</value> </resheader> <resheader name="reader"> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <data name="AvoidWaitForDelay_ProblemDescription" xml:space="preserve"> <value>WAITFOR DELAY statement was found in {0}</value> </data> <data name="AvoidWaitFormDelay_RuleName" xml:space="preserve"> <value>Avoid using WaitFor Delay statements in stored procedures, functions and triggers.</value> </data> <data name="CategorySamples" xml:space="preserve"> <value>SamplesCategory</value> </data> <data name="CannotCreateResourceManager" xml:space="preserve"> <value>Can't create ResourceManager for {0} from {1}</value> </data> </root>
Spara filen
RuleResources.resx
.Öppna filen
SampleRules.csproj
och lägg till följande kod för att uppdatera och inkludera resursinnehållet i projektet:<ItemGroup> <Compile Update="RuleResources.Designer.cs"> <DesignTime>True</DesignTime> <AutoGen>True</AutoGen> <DependentUpon>RuleResources.resx</DependentUpon> </Compile> </ItemGroup> <ItemGroup> <EmbeddedResource Include="RuleResources.resx"> <Generator>PublicResXFileCodeGenerator</Generator> <LastGenOutput>RuleResources.Designer.cs</LastGenOutput> </EmbeddedResource> </ItemGroup>
Spara filen
SampleRules.csproj
.
I katalogen
SampleRules
skapar du en ny fil med namnetRuleResources.resx
.Öppna filen
RuleResources.resx
och lägg till följande kod:<?xml version="1.0" encoding="utf-8"?> <root> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:element name="root" msdata:IsDataSet="true"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="metadata"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" /> </xsd:sequence> <xsd:attribute name="name" use="required" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" /> <xsd:attribute ref="xml:space" /> </xsd:complexType> </xsd:element> <xsd:element name="assembly"> <xsd:complexType> <xsd:attribute name="alias" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" /> </xsd:complexType> </xsd:element> <xsd:element name="data"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> <xsd:attribute ref="xml:space" /> </xsd:complexType> </xsd:element> <xsd:element name="resheader"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" /> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:schema> <resheader name="resmimetype"> <value>text/microsoft-resx</value> </resheader> <resheader name="version"> <value>2.0</value> </resheader> <resheader name="reader"> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <data name="AvoidWaitForDelay_ProblemDescription" xml:space="preserve"> <value>WAITFOR DELAY statement was found in {0}</value> </data> <data name="AvoidWaitFormDelay_RuleName" xml:space="preserve"> <value>Avoid using WaitFor Delay statements in stored procedures, functions and triggers.</value> </data> <data name="CategorySamples" xml:space="preserve"> <value>SamplesCategory</value> </data> <data name="CannotCreateResourceManager" xml:space="preserve"> <value>Can't create ResourceManager for {0} from {1}</value> </data> </root>
Spara filen
RuleResources.resx
.Öppna filen
SampleRules.csproj
och lägg till följande kod för att uppdatera och inkludera resursinnehållet i projektet:<ItemGroup> <Compile Update="RuleResources.Designer.cs"> <DesignTime>True</DesignTime> <AutoGen>True</AutoGen> <DependentUpon>RuleResources.resx</DependentUpon> </Compile> </ItemGroup> <ItemGroup> <EmbeddedResource Include="RuleResources.resx"> <Generator>PublicResXFileCodeGenerator</Generator> <LastGenOutput>RuleResources.Designer.cs</LastGenOutput> </EmbeddedResource> </ItemGroup>
Spara filen
SampleRules.csproj
.
Steg 2.3: Definiera klassen LocalizedExportCodeAnalysisRuleAttribute
Den andra klassen är LocalizedExportCodeAnalysisRuleAttribute.cs
. Det här är ett tillägg till den inbyggda Microsoft.SqlServer.Dac.CodeAnalysis.ExportCodeAnalysisRuleAttribute
som tillhandahålls av ramverket och stöder läsning av DisplayName
och Description
som används av regeln från en resursfil. Det här är en användbar klass om du tänker använda dina regler på flera språk.
I Solution Explorerväljer du projektet
SampleRules
.På menyn Project väljer du Lägg till klass. Dialogrutan Lägg till nytt objekt visas. I textrutan Namn skriver du
LocalizedExportCodeAnalysisRuleAttribute.cs
och väljer sedan knappen Lägg till. Filen läggs till i projektet i Solution Explorer.
I Solution Explorerväljer du projektet
SampleRules
.På menyn Project väljer du Lägg till klass. Dialogrutan Lägg till nytt objekt visas. I textrutan Namn skriver du
LocalizedExportCodeAnalysisRuleAttribute.cs
och väljer sedan knappen Lägg till. Filen läggs till i projektet i Solution Explorer.
- Navigera till katalogen
SampleRules
i Explorer i Visual Studio Code. - Skapa en ny fil med namnet
LocalizedExportCodeAnalysisRuleAttribute.cs
.
- Gå till katalogen
SampleRules
. - Skapa en ny fil med namnet
LocalizedExportCodeAnalysisRuleAttribute.cs
.
Öppna filen och uppdatera innehållet så att det matchar följande kod:
using Microsoft.SqlServer.Dac.CodeAnalysis; using System; using System.Globalization; using System.Reflection; using System.Resources; namespace SampleRules { internal class LocalizedExportCodeAnalysisRuleAttribute : ExportCodeAnalysisRuleAttribute { private readonly string _resourceBaseName; private readonly string _displayNameResourceId; private readonly string _descriptionResourceId; private ResourceManager _resourceManager; private string _displayName; private string _descriptionValue; /// <summary> /// Creates the attribute, with the specified rule ID, the fully qualified /// name of the resource file that will be used for looking up display name /// and description, and the Ids of those resources inside the resource file. /// </summary> public LocalizedExportCodeAnalysisRuleAttribute( string id, string resourceBaseName, string displayNameResourceId, string descriptionResourceId) : base(id, null) { _resourceBaseName = resourceBaseName; _displayNameResourceId = displayNameResourceId; _descriptionResourceId = descriptionResourceId; } /// <summary> /// Rules in a different assembly would need to overwrite this /// </summary> /// <returns></returns> protected virtual Assembly GetAssembly() { return GetType().Assembly; } private void EnsureResourceManagerInitialized() { var resourceAssembly = GetAssembly(); try { _resourceManager = new ResourceManager(_resourceBaseName, resourceAssembly); } catch (Exception ex) { var msg = String.Format(CultureInfo.CurrentCulture, RuleResources.CannotCreateResourceManager, _resourceBaseName, resourceAssembly); throw new RuleException(msg, ex); } } private string GetResourceString(string resourceId) { EnsureResourceManagerInitialized(); return _resourceManager.GetString(resourceId, CultureInfo.CurrentUICulture); } /// <summary> /// Overrides the standard DisplayName and looks up its value inside a resources file /// </summary> public override string DisplayName { get { if (_displayName == null) { _displayName = GetResourceString(_displayNameResourceId); } return _displayName; } } /// <summary> /// Overrides the standard Description and looks up its value inside a resources file /// </summary> public override string Description { get { if (_descriptionValue == null) { _descriptionValue = GetResourceString(_descriptionResourceId); } return _descriptionValue; } } } }
Steg 2.4: Definiera klassen SampleConstants
Definiera sedan en klass som refererar till resurserna i resursfilen som används av Visual Studio för att visa information om regeln i användargränssnittet.
I Solution Explorerväljer du projektet
SampleRules
.På menyn Project väljer du Lägg till och sedan Klass. Dialogrutan Lägg till nytt objekt visas. I textrutan Namn skriver du
SampleRuleConstants.cs
och väljer knappen Lägg till. FilenSampleRuleConstants.cs
läggs till i projektet i Solution Explorer.
I Solution Explorerväljer du projektet
SampleRules
.På menyn Project väljer du Lägg till och sedan Klass. Dialogrutan Lägg till nytt objekt visas. I textrutan Namn skriver du
SampleRuleConstants.cs
och väljer knappen Lägg till. FilenSampleRuleConstants.cs
läggs till i projektet i Solution Explorer.
- Navigera till katalogen
SampleRules
i Explorer i Visual Studio Code. - Skapa en ny fil med namnet
SampleRuleConstants.cs
.
- Gå till katalogen
SampleRules
. - Skapa en ny fil med namnet
SampleRuleConstants.cs
.
Öppna filen
SampleRuleConstants.cs
och lägg till följande using-instruktioner i filen:namespace SampleRules { internal static class RuleConstants { /// <summary> /// The name of the resources file to use when looking up rule resources /// </summary> public const string ResourceBaseName = "SampleRules.RuleResources"; /// <summary> /// Lookup name inside the resources file for the select asterisk rule name /// </summary> public const string AvoidWaitForDelay_RuleName = "AvoidWaitForDelay_RuleName"; /// <summary> /// Lookup ID inside the resources file for the select asterisk description /// </summary> public const string AvoidWaitForDelay_ProblemDescription = "AvoidWaitForDelay_ProblemDescription"; /// <summary> /// The design category (should not be localized) /// </summary> public const string CategoryDesign = "Design"; /// <summary> /// The performance category (should not be localized) /// </summary> public const string CategoryPerformance = "Design"; } }
På menyn Arkiv väljer du Spara.
Steg 3: Skapa en anpassad regelklass
När du har lagt till hjälpklasserna som den anpassade kodanalysregeln ska använda skapar du en anpassad regelklass och ger den namnet AvoidWaitForDelayRule
. Den AvoidWaitForDelayRule
anpassade regeln används för att hjälpa databasutvecklare att undvika WAITFOR DELAY
instruktioner i lagrade procedurer, utlösare och funktioner.
Steg 3.1: Skapa klassen AvoidWaitForDelayRule
I Solution Explorerväljer du projektet
SampleRules
.På menyn Project väljer du Lägg till och sedan Klass. Dialogrutan Lägg till nytt objekt visas. I textrutan Namn skriver du
AvoidWaitForDelayRule.cs
och väljer sedan Lägg till. FilenAvoidWaitForDelayRule.cs
läggs till i projektet i Solution Explorer.
I Solution Explorerväljer du projektet
SampleRules
.På menyn Project väljer du Lägg till och sedan Klass. Dialogrutan Lägg till nytt objekt visas. I textrutan Namn skriver du
AvoidWaitForDelayRule.cs
och väljer sedan Lägg till. FilenAvoidWaitForDelayRule.cs
läggs till i projektet i Solution Explorer.
- Navigera till katalogen
SampleRules
i Explorer i Visual Studio Code. - Skapa en ny fil med namnet
AvoidWaitForDelayRule.cs
.
- Gå till katalogen
SampleRules
. - Skapa en ny fil med namnet
AvoidWaitForDelayRule.cs
.
Öppna filen
AvoidWaitForDelayRule.cs
och lägg till följande using-instruktioner i filen:using Microsoft.SqlServer.Dac.CodeAnalysis; using Microsoft.SqlServer.Dac.Model; using Microsoft.SqlServer.TransactSql.ScriptDom; using System; using System.Collections.Generic; using System.Globalization; namespace SampleRules { class AvoidWaitForDelayRule {} }
I
AvoidWaitForDelayRule
-klassdeklarationen ändrar du åtkomstmodifieraren till offentlig:/// <summary> /// This is a rule that returns a warning message /// whenever there is a WAITFOR DELAY statement appears inside a subroutine body. /// This rule only applies to stored procedures, functions and triggers. /// </summary> public sealed class AvoidWaitForDelayRule
Härled klassen
AvoidWaitForDelayRule
från basklassenMicrosoft.SqlServer.Dac.CodeAnalysis.SqlCodeAnalysisRule
:public sealed class AvoidWaitForDelayRule : SqlCodeAnalysisRule
Lägg till
LocalizedExportCodeAnalysisRuleAttribute
i klassen.LocalizedExportCodeAnalysisRuleAttribute
gör att kodanalystjänsten kan identifiera anpassade kodanalysregler. Endast klasser som har markerats med enExportCodeAnalysisRuleAttribute
(eller ett attribut som ärver från detta) kan användas i kodanalys.LocalizedExportCodeAnalysisRuleAttribute
innehåller vissa nödvändiga metadata som används av tjänsten. Detta inkluderar ett unikt ID för den här regeln, ett visningsnamn som visas i Visual Studio-användargränssnittet och enDescription
som kan användas av regeln när du identifierar problem.[LocalizedExportCodeAnalysisRule(AvoidWaitForDelayRule.RuleId, RuleConstants.ResourceBaseName, RuleConstants.AvoidWaitForDelay_RuleName, RuleConstants.AvoidWaitForDelay_ProblemDescription Category = RuleConstants.CategoryPerformance, RuleScope = SqlRuleScope.Element)] public sealed class AvoidWaitForDelayRule : SqlCodeAnalysisRule { /// <summary> /// The Rule ID should resemble a fully-qualified class name. In the Visual Studio UI /// rules are grouped by "Namespace + Category", and each rule is shown using "Short ID: DisplayName". /// For this rule, that means the grouping will be "Public.Dac.Samples.Performance", with the rule /// shown as "SR1004: Avoid using WaitFor Delay statements in stored procedures, functions and triggers." /// </summary> public const string RuleId = "RuleSamples.SR1004"; }
Egenskapen RuleScope bör vara
Microsoft.SqlServer.Dac.CodeAnalysis.SqlRuleScope.Element
eftersom den här regeln analyserar specifika element. Regeln anropas en gång för varje matchande element i modellen. Om du vill analysera en hel modell kanMicrosoft.SqlServer.Dac.CodeAnalysis.SqlRuleScope.Model
användas i stället.Lägg till en konstruktor som konfigurerar
Microsoft.SqlServer.Dac.CodeAnalysis.SqlAnalysisRule.SupportedElementTypes
. Detta krävs för regler med elementomfattning. Den definierar de typer av element som den här regeln gäller för. I det här fallet tillämpas regeln på lagrade procedurer, utlösare och funktioner. KlassenMicrosoft.SqlServer.Dac.Model.ModelSchema
listar alla tillgängliga elementtyper som kan analyseras.public AvoidWaitForDelayRule() { // This rule supports Procedures, Functions and Triggers. Only those objects will be passed to the Analyze method SupportedElementTypes = new[] { // Note: can use the ModelSchema definitions, or access the TypeClass for any of these types ModelSchema.ExtendedProcedure, ModelSchema.Procedure, ModelSchema.TableValuedFunction, ModelSchema.ScalarFunction, ModelSchema.DatabaseDdlTrigger, ModelSchema.DmlTrigger, ModelSchema.ServerDdlTrigger }; }
Lägg till en åsidosättning för metoden
Microsoft.SqlServer.Dac.CodeAnalysis.SqlAnalysisRule.Analyze
(Microsoft.SqlServer.Dac.CodeAnalysis.SqlRuleExecutionContext)
, som använderMicrosoft.SqlServer.Dac.CodeAnalysis.SqlRuleExecutionContext
som indataparametrar. Den här metoden returnerar en lista över potentiella problem.Metoden hämtar
Microsoft.SqlServer.Dac.Model.TSqlModel
,Microsoft.SqlServer.Dac.Model.TSqlObject
och TSqlFragment från kontextparametern. KlassenWaitForDelayVisitor
används sedan för att hämta en lista över allaWAITFOR DELAY
-instruktioner i modellen.För varje WaitForStatement- i listan skapas en
Microsoft.SqlServer.Dac.CodeAnalysis.SqlRuleProblem
./// <summary> /// For element-scoped rules the Analyze method is executed once for every matching /// object in the model. /// </summary> /// <param name="ruleExecutionContext">The context object contains the TSqlObject being /// analyzed, a TSqlFragment /// that's the AST representation of the object, the current rule's descriptor, and a /// reference to the model being /// analyzed. /// </param> /// <returns>A list of problems should be returned. These will be displayed in the Visual /// Studio error list</returns> public override IList<SqlRuleProblem> Analyze( SqlRuleExecutionContext ruleExecutionContext) { IList<SqlRuleProblem> problems = new List<SqlRuleProblem>(); TSqlObject modelElement = ruleExecutionContext.ModelElement; // this rule does not apply to inline table-valued function // we simply do not return any problem in that case. if (IsInlineTableValuedFunction(modelElement)) { return problems; } string elementName = GetElementName(ruleExecutionContext, modelElement); // The rule execution context has all the objects we'll need, including the // fragment representing the object, // and a descriptor that lets us access rule metadata TSqlFragment fragment = ruleExecutionContext.ScriptFragment; RuleDescriptor ruleDescriptor = ruleExecutionContext.RuleDescriptor; // To process the fragment and identify WAITFOR DELAY statements we will use a // visitor WaitForDelayVisitor visitor = new WaitForDelayVisitor(); fragment.Accept(visitor); IList<WaitForStatement> waitforDelayStatements = visitor.WaitForDelayStatements; // Create problems for each WAITFOR DELAY statement found // When creating a rule problem, always include the TSqlObject being analyzed. This // is used to determine // the name of the source this problem was found in and a best guess as to the // line/column the problem was found at. // // In addition if you have a specific TSqlFragment that is related to the problem //also include this // since the most accurate source position information (start line and column) will // be read from the fragment foreach (WaitForStatement waitForStatement in waitforDelayStatements) { SqlRuleProblem problem = new SqlRuleProblem( String.Format(CultureInfo.CurrentCulture, ruleDescriptor.DisplayDescription, elementName), modelElement, waitForStatement); problems.Add(problem); } return problems; } private static string GetElementName( SqlRuleExecutionContext ruleExecutionContext, TSqlObject modelElement) { // Get the element name using the built in DisplayServices. This provides a number of // useful formatting options to // make a name user-readable var displayServices = ruleExecutionContext.SchemaModel.DisplayServices; string elementName = displayServices.GetElementName( modelElement, ElementNameStyle.EscapedFullyQualifiedName); return elementName; } private static bool IsInlineTableValuedFunction(TSqlObject modelElement) { return TableValuedFunction.TypeClass.Equals(modelElement.ObjectType) && FunctionType.InlineTableValuedFunction == modelElement.GetMetadata<FunctionType>(TableValuedFunction.FunctionType); }
På menyn Arkiv väljer du Spara.
Steg 4: Skapa klassbiblioteket
- På menyn Project väljer du SampleRules Properties.
- Välj fliken signering.
- Välj Signera sammansättningen.
- I Välj en stark namnnyckelfil, välj <Ny>.
- I dialogrutan Skapa stark namnnyckel skriver du
MyRefKey
i Nyckelfilnamn. - (valfritt) Du kan ange ett lösenord för din starka namnnyckelfil.
- Välj OK.
- På menyn Arkiv väljer du Spara alla.
- På menyn Build väljer du Build Solution.
- På menyn Project väljer du SampleRules Properties.
- Välj fliken Signering.
- Välj Signera sammansättningen.
- I Välj en stark namnnyckelfil, välj <Ny>.
- I dialogrutan Skapa stark namnnyckel skriver du
MyRefKey
i Nyckelfilnamn. - (valfritt) Du kan ange ett lösenord för din starka namnnyckelfil.
- Välj OK.
- På menyn Arkiv väljer du Spara allt.
- På menyn Build väljer du Build Solution.
Öppna fönstret Terminal i Visual Studio Code genom att välja menyn Visa och sedan Terminal.
I Terminalanger du följande kommando för att skapa projektet:
dotnet build /p:Configuration=Release
Gå till katalogen
SampleRules
.Kör följande kommando för att skapa projektet:
dotnet build /p:Configuration=Release
Steg 5: Installera och testa den nya kodanalysregeln
Därefter måste du installera sammansättningen så att den läses in när du skapar ett SQL-databasprojekt.
Om du vill installera en regel som ska köras när du skapar ett ursprungligt SQL-projekt med Visual Studio måste du kopiera sammansättningen och tillhörande .pdb
fil till mappen Tillägg.
Steg 5.1: Installera SampleRules-sammansättningen
- Kopiera sedan sammansättningsinformationen till Extensions-katalogen. När Visual Studio startar identifieras eventuella tillägg i
<Visual Studio Install Dir>\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\Extensions
katalog och underkataloger och gör dem tillgängliga för användning. För Visual Studio 2022 är<Visual Studio Install Dir>
vanligtvisC:\Program Files\Microsoft Visual Studio\2022\Enterprise
. ErsättEnterprise
medProfessional
ellerCommunity
beroende på vilken Visual Studio-version du har installerat. - Kopiera
SampleRules.dll
sammansättningsfilen från utdatakatalogen till katalogen<Visual Studio Install Dir>\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\Extensions
. Som standard är sökvägen till den kompilerade.dll
filenYourSolutionPath\YourProjectPath\bin\Debug
ellerYourSolutionPath\YourProjectPath\bin\Release
.
Not
Du kan behöva skapa katalogen Extensions
.
Regeln bör nu installeras och visas när du startar om Visual Studio. Starta sedan en ny session i Visual Studio och skapa ett databasprojekt.
Steg 5.2: Starta en ny Visual Studio-session och skapa ett databasprojekt
- Starta en andra session i Visual Studio.
- Välj Fil>Nytt>Projekt.
- I dialogrutan Nytt projekt letar du upp och väljer SQL Server Database Project.
- I textrutan Namn skriver du
SampleRulesDB
och väljer OK.
Steg 5.3: Aktivera regeln AvoidWaitForRule för kodanalys
- I Solution Explorerväljer du projektet
SampleRulesDB
. - På menyn Project väljer du Egenskaper. Sidan för
SampleRulesDB
-egenskaper visas. - Välj kodanalys. Du bör se en ny kategori med namnet
RuleSamples.CategorySamples
. - Expandera
RuleSamples.CategorySamples
. Du bör seSR1004: Avoid WAITFOR DELAY statement in stored procedures, triggers, and functions
. - Aktivera den här regeln genom att markera kryssrutan bredvid regelnamnet och kryssrutan för Aktivera kodanalys på build-. Mer information om hur du aktiverar kodanalys finns i översikten över kodanalys.
- När projektet skapa åtgärd används körs regeln och eventuella
WAITFOR DELAY
-instruktioner som hittas rapporteras som varningar.
Om du vill installera en regel som ska köras när du skapar ett ursprungligt SQL-projekt med Visual Studio måste du kopiera sammansättningen och tillhörande .pdb
fil till mappen Tillägg.
Steg 5.1: Installera SampleRules-sammansättningen
- Kopiera sedan sammansättningsinformationen till mappen Tillägg. När Visual Studio startar identifieras eventuella tillägg i
<Visual Studio Install Dir>\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\Extensions
katalog och underkataloger och gör dem tillgängliga för användning. För Visual Studio 2022 är<Visual Studio Install Dir>
vanligtvisC:\Program Files\Microsoft Visual Studio\2022\Enterprise
. ErsättEnterprise
medProfessional
ellerCommunity
beroende på din installerade Visual Studio-version. - Kopiera
SampleRules.dll
sammansättningsfilen från utdatakatalogen till katalogen<Visual Studio Install Dir>\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\Extensions
. Som standard är sökvägen till den kompilerade.dll
filenYourSolutionPath\YourProjectPath\bin\Debug
ellerYourSolutionPath\YourProjectPath\bin\Release
.
Not
Du kan behöva skapa katalogen Extensions
.
Regeln bör nu installeras och visas när du startar om Visual Studio. Starta sedan en ny session i Visual Studio och skapa ett databasprojekt.
Steg 5.2: Starta en ny Visual Studio-session och skapa ett databasprojekt
- Starta en andra session i Visual Studio.
- Välj Fil>Nytt>Projekt.
- I dialogrutan Nytt projekt letar du upp och väljer SQL Server Database Project, SDK-format (förhandsversion).
- I textrutan Namn skriver du
SampleRulesDB
och väljer OK.
Steg 5.3: Aktivera regeln för kodanalys - AvoidWaitForRule
- I Solution Explorerväljer du projektet
SampleRulesDB
. - Dubbelklicka på projektnoden för att öppna projektfilen. Den
SampleRulesDB
projektfilen visas i en textredigerare. - Aktivera kodanalys på build- i SQL-projektfilen genom att ange egenskapen
RunSqlCodeAnalysis
tilltrue
. - När åtgärden bygga i projekt används, kommer regeln att köras och eventuella
WAITFOR DELAY
-instruktioner som finns kommer att rapporteras som varningar.
Steg 5.1: Placera SampleRules-sammansättningen i en lokal NuGet-källa
- Om du inte har någon lokal källa för NuGet-paket lägger du till en mapp på den lokala datorn för att lagra NuGet-paketen för lokal testning. Du kan kontrollera dina aktuella NuGet-källor genom att köra följande kommando:
dotnet nuget list source
- Om en lokal källa inte visas kan du lägga till en med hjälp av följande kommando och ersätta
<local folder path>
med sökvägen till den lokala mappen, till exempelC:\NuGetPackages
eller~/NuGetPackages
:
dotnet nuget add source <local folder path>
- Kopiera
SampleRules.dll
sammansättningsfilen från utdatakatalogen till den lokala NuGet-källkatalogen. Som standard är sökvägen till den kompilerade.dll
filenYourSolutionPath\YourProjectPath\bin\Debug
ellerYourSolutionPath\YourProjectPath\bin\Release
.
Steg 5.2: Använda SampleRules i ett databasprojekt
- Skapa ett nytt Microsoft.Build.Sql-projekt eller öppna ett befintligt projekt.
- Lägg till en paketreferens till SampleRules NuGet-paketet i projektfilen. I följande exempel visas hur du lägger till en referens till SampleRules NuGet-paketet i filen
.sqlproj
:
<ItemGroup>
<PackageReference Include="SampleRules" Version="1.0.0" />
</ItemGroup>
Steg 5.3: Aktivera kodanalys vid bygge
- Aktivera kodanalys på build- i SQL-projektfilen genom att ange egenskapen
RunSqlCodeAnalysis
tilltrue
. NuGet-paketet SampleRules återställs när projektet skapas och ingår som standard. - När projektet skapa åtgärd används körs regeln och eventuella
WAITFOR DELAY
-instruktioner som hittas rapporteras som varningar.
Steg 5.1: Placera SampleRules-sammansättningen i en lokal NuGet-källa
- Om du inte har någon lokal källa för NuGet-paket lägger du till en mapp på den lokala datorn för att lagra NuGet-paketen för lokal testning. Du kan kontrollera dina aktuella NuGet-källor genom att köra följande kommando:
dotnet nuget list source
- Om en lokal källa inte visas kan du lägga till en med hjälp av följande kommando och ersätta
<local folder path>
med sökvägen till den lokala mappen, till exempelC:\NuGetPackages
eller~/NuGetPackages
:
dotnet nuget add source <local folder path>
- Kopiera
SampleRules.dll
sammansättningsfilen från utdatakatalogen till den lokala NuGet-källkatalogen. Som standard är sökvägen till den kompilerade.dll
filenYourSolutionPath\YourProjectPath\bin\Debug
ellerYourSolutionPath\YourProjectPath\bin\Release
.
Steg 5.2: Använda SampleRules i ett databasprojekt
- Skapa ett nytt Microsoft.Build.Sql-projekt eller öppna ett befintligt projekt.
- Lägg till en paketreferens till SampleRules NuGet-paketet i projektfilen. I följande exempel visas hur du lägger till en referens till SampleRules NuGet-paketet i filen
.sqlproj
:
<ItemGroup>
<PackageReference Include="SampleRules" Version="1.0.0" />
</ItemGroup>
Steg 5.3: Aktivera kodanalys vid bygge
- Aktivera kodanalys på build- i SQL-projektfilen genom att ange egenskapen
RunSqlCodeAnalysis
tilltrue
. NuGet-paketet SampleRules återställs när projektet skapas och ingår som standard. - När byggåtgärden för projekt används, kommer regeln att köras och eventuella
WAITFOR DELAY
-instruktioner som hittas rapporteras som varningar.