Udostępnij za pośrednictwem


Instrukcja: Rozszerzanie procesu wdrażania projektu bazy danych do analizy planu wdrożenia

Możesz tworzyć współpracowników wdrożeń, aby wykonywać niestandardowe akcje podczas wdrażania projektu SQL. Można utworzyć moduł DeploymentPlanModifier lub DeploymentPlanExecutor. Użyj elementu DeploymentPlanModifier, aby zmienić plan przed jego wykonaniem, a element DeploymentPlanExecutor do wykonywania operacji podczas wykonywania planu. W tym przewodniku utworzysz obiekt DeploymentPlanExecutor o nazwie DeploymentUpdateReportContributor, który tworzy raport o akcjach wykonywanych podczas wdrażania projektu bazy danych. Ponieważ ten współautor kompilacji akceptuje parametr służący do kontrolowania, czy raport jest generowany, należy wykonać dodatkowy wymagany krok.

W tym przewodniku wykonasz następujące główne zadania:

Warunki wstępne

Do ukończenia tego przewodnika potrzebne są następujące składniki:

  • Musisz mieć zainstalowaną wersję programu Visual Studio, która zawiera narzędzia SQL Server Data Tools (SSDT) i obsługuje programowanie w języku C# lub VB.

  • Musisz mieć projekt SQL zawierający obiekty SQL.

  • Wystąpienie programu SQL Server, w którym można wdrożyć projekt bazy danych.

Notatka

Ten przewodnik jest przeznaczony dla użytkowników, którzy znają już funkcje SQL programu SSDT. Oczekuje się również, że zapoznasz się z podstawowymi pojęciami programu Visual Studio, takimi jak tworzenie biblioteki klas i używanie edytora kodu do dodawania kodu do klasy.

Tworzenie współautora wdrożenia

Aby utworzyć współautora wdrożenia, należy wykonać następujące zadania:

  • Utwórz projekt biblioteki klas i dodaj wymagane odwołania.

  • Zdefiniuj klasę o nazwie DeploymentUpdateReportContributor, która dziedziczy z DeploymentPlanExecutor.

  • Nadpisz metodę OnExecute.

  • Dodaj prywatną klasę pomocniczą.

  • Skompiluj wynikowy zestaw.

Aby utworzyć projekt biblioteki klas

  1. Utwórz projekt biblioteki klas Visual Basic lub Visual C# o nazwie MyDeploymentContributor.

  2. Zmień nazwę pliku "Class1.cs" na "DeploymentUpdateReportContributor.cs".

  3. W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy węzeł projektu, a następnie kliknij Dodaj odwołanie.

  4. Wybierz System.ComponentModel.Composition na karcie Struktury.

  5. Dodaj wymagane odwołania SQL: kliknij prawym przyciskiem myszy węzeł projektu, a następnie kliknij Dodaj odwołanie. Kliknij Przeglądaj i przejdź do folderu C:\Program Files (x86)\Microsoft SQL Server\110\DAC\Bin. Wybierz wpisy Microsoft.SqlServer.Dac.dll, Microsoft.SqlServer.Dac.Extensions.dlli Microsoft.Data.Tools.Schema.Sql.dll, kliknij przycisk Dodaj, a następnie kliknij przycisk OK.

    Następnie zacznij dodawać kod do klasy.

Aby zdefiniować klasę DeploymentUpdateReportContributor

  1. W edytorze kodu zaktualizuj plik DeploymentUpdateReportContributor.cs, aby był zgodny z następującymi instrukcjami użycia i.

    using System;  
    using System.IO;  
    using System.Text;  
    using System.Xml;  
    using Microsoft.SqlServer.Dac.Deployment;  
    using Microsoft.SqlServer.Dac.Extensibility;  
    using Microsoft.SqlServer.Dac.Model;  
    
    
  2. Zaktualizuj definicję klasy, aby odpowiadała następującej zawartości:

    /// <summary>  
        /// An executor that generates a report detailing the steps in the deployment plan. Will only run  
        /// if a "GenerateUpdateReport=true" contributor argument is set in the project file, in a targets file or  
        /// passed as an additional argument to the DacServices API. To set in a project file, add the following:  
        ///   
        /// <PropertyGroup>  
        ///     <ContributorArguments Condition="'$(Configuration)' == 'Debug'">  
        /// $(ContributorArguments);DeploymentUpdateReportContributor.GenerateUpdateReport=true;  
        ///     </ContributorArguments>  
        /// <PropertyGroup>  
        ///   
        /// </summary>  
        [ExportDeploymentPlanExecutor("MyDeploymentContributor.DeploymentUpdateReportContributor", "1.0.0.0")]  
        public class DeploymentUpdateReportContributor : DeploymentPlanExecutor  
        {  
        }  
    
    

    Teraz zdefiniowano współautora wdrożenia, który dziedziczy z elementu DeploymentPlanExecutor. Podczas procesów kompilacji i wdrażania niestandardowe składniki są wczytywane ze standardowego katalogu rozszerzeń. Współautorzy funkcji wykonawczej planu wdrożenia są identyfikowani przez atrybut ExportDeploymentPlanExecutor.

    Ten atrybut jest wymagany, aby można było odnaleźć współautorów. Powinien wyglądać podobnie do następującego przykładu:

    [ExportDeploymentPlanExecutor("MyDeploymentContributor.DeploymentUpdateReportContributor", "1.0.0.0")]  
    
    

    W takim przypadku pierwszy parametr atrybutu powinien być unikatowym identyfikatorem — służy do identyfikowania współautora w plikach projektu. Najlepszą praktyką jest połączenie przestrzeni nazw biblioteki — w tym przykładzie MyDeploymentContributor — z nazwą klasy — w tym przykładzie DeploymentUpdateReportContributor — aby utworzyć identyfikator.

  3. Następnie dodaj następujący element, którego użyjesz, aby umożliwić temu provider’owi akceptowanie parametru wiersza polecenia:

    public const string GenerateUpdateReport = "DeploymentUpdateReportContributor.GenerateUpdateReport";  
    

    Ten element członkowski umożliwia użytkownikowi określenie, czy raport powinien zostać wygenerowany przy użyciu opcji GenerateUpdateReport.

    Następnie zastąpisz metodę OnExecute, aby dodać kod, który chcesz uruchomić po wdrożeniu projektu bazy danych.

Aby przesłonić OnExecute

  • Dodaj następującą metodę do klasy DeploymentUpdateReportContributor:

    /// <summary>  
            /// Override the OnExecute method to perform actions when you execute the deployment plan for  
            /// a database project.  
            /// </summary>  
            protected override void OnExecute(DeploymentPlanContributorContext context)  
            {  
                // determine whether the user specified a report is to be generated  
                bool generateReport = false;  
                string generateReportValue;  
                if (context.Arguments.TryGetValue(GenerateUpdateReport, out generateReportValue) == false)  
                {  
                    // couldn't find the GenerateUpdateReport argument, so do not generate  
                    generateReport = false;  
                }  
                else  
                {  
                    // GenerateUpdateReport argument was specified, try to parse the value  
                    if (bool.TryParse(generateReportValue, out generateReport))  
                    {  
                        // if we end up here, the value for the argument was not valid.  
                        // default is false, so do nothing.  
                    }  
                }  
    
                if (generateReport == false)  
                {  
                    // if user does not want to generate a report, we are done  
                    return;  
                }  
    
                // We will output to the same directory where the deployment script  
                // is output or to the current directory  
                string reportPrefix = context.Options.TargetDatabaseName;  
                string reportPath;  
                if (string.IsNullOrEmpty(context.DeploymentScriptPath))  
                {  
                    reportPath = Environment.CurrentDirectory;  
                }  
                else  
                {  
                    reportPath = Path.GetDirectoryName(context.DeploymentScriptPath);  
                }  
                FileInfo summaryReportFile = new FileInfo(Path.Combine(reportPath, reportPrefix + ".summary.xml"));  
                FileInfo detailsReportFile = new FileInfo(Path.Combine(reportPath, reportPrefix + ".details.xml"));  
    
                // Generate the reports by using the helper class DeploymentReportWriter  
                DeploymentReportWriter writer = new DeploymentReportWriter(context);  
                writer.WriteReport(summaryReportFile);  
                writer.IncludeScripts = true;  
                writer.WriteReport(detailsReportFile);  
    
                string msg = "Deployment reports ->"  
                    + Environment.NewLine + summaryReportFile.FullName  
                    + Environment.NewLine + detailsReportFile.FullName;  
    
                ExtensibilityError reportMsg = new ExtensibilityError(msg, Severity.Message);  
                base.PublishMessage(reportMsg);  
            }  
        /// <summary>  
        /// Override the OnExecute method to perform actions when you execute the deployment plan for  
        /// a database project.  
        /// </summary>  
            protected override void OnExecute(DeploymentPlanContributorContext context)  
            {  
                // determine whether the user specified a report is to be generated  
                bool generateReport = false;  
                string generateReportValue;  
                if (context.Arguments.TryGetValue(GenerateUpdateReport, out generateReportValue) == false)  
                {  
                    // couldn't find the GenerateUpdateReport argument, so do not generate  
                    generateReport = false;  
                }  
                else  
                {  
                    // GenerateUpdateReport argument was specified, try to parse the value  
                    if (bool.TryParse(generateReportValue, out generateReport))  
                    {  
                        // if we end up here, the value for the argument was not valid.  
                        // default is false, so do nothing.  
                    }  
                }  
    
                if (generateReport == false)  
                {  
                    // if user does not want to generate a report, we are done  
                    return;  
                }  
    
                // We will output to the same directory where the deployment script  
                // is output or to the current directory  
                string reportPrefix = context.Options.TargetDatabaseName;  
                string reportPath;  
                if (string.IsNullOrEmpty(context.DeploymentScriptPath))  
                {  
                    reportPath = Environment.CurrentDirectory;  
                }  
                else  
                {  
                    reportPath = Path.GetDirectoryName(context.DeploymentScriptPath);  
                }  
                FileInfo summaryReportFile = new FileInfo(Path.Combine(reportPath, reportPrefix + ".summary.xml"));  
                FileInfo detailsReportFile = new FileInfo(Path.Combine(reportPath, reportPrefix + ".details.xml"));  
    
                // Generate the reports by using the helper class DeploymentReportWriter  
                DeploymentReportWriter writer = new DeploymentReportWriter(context);  
                writer.WriteReport(summaryReportFile);  
                writer.IncludeScripts = true;  
                writer.WriteReport(detailsReportFile);  
    
                string msg = "Deployment reports ->"  
                    + Environment.NewLine + summaryReportFile.FullName  
                    + Environment.NewLine + detailsReportFile.FullName;  
    
                DataSchemaError reportMsg = new DataSchemaError(msg, ErrorSeverity.Message);  
                base.PublishMessage(reportMsg);  
            }  
    

    Do metody OnExecute jest przekazywany obiekt DeploymentPlanContributorContext, który zapewnia dostęp do wskazanych argumentów, modeli bazy danych źródłowej i docelowej, właściwości kompilacji i plików rozszerzeń. W tym przykładzie uzyskamy model, a następnie wywołamy funkcje pomocnika, aby uzyskać informacje o modelu. Używamy metody pomocnika PublishMessage w klasie bazowej, aby zgłosić wszelkie błędy, które występują.

    Dodatkowe typy i interesujące metody to: TSqlModel, ModelComparisonResult, DeploymentPlanHandlei SqlDeploymentOptions.

    Następnie zdefiniujesz klasę pomocnika, która zagłębia się w szczegóły planu wdrożenia.

Aby dodać klasę pomocnika, która generuje treść raportu

  • Dodaj klasę pomocnika i jej metody, dodając następujący kod:

    /// <summary>  
            /// This class is used to generate a deployment  
            /// report.   
            /// </summary>  
            private class DeploymentReportWriter  
            {  
                readonly TSqlModel _sourceModel;  
                readonly ModelComparisonResult _diff;  
                readonly DeploymentStep _planHead;  
    
                /// <summary>  
                /// The constructor accepts the same context info  
                /// that was passed to the OnExecute method of the  
                /// deployment contributor.  
                /// </summary>  
                public DeploymentReportWriter(DeploymentPlanContributorContext context)  
                {  
                    if (context == null)  
                    {  
                        throw new ArgumentNullException("context");  
                    }  
    
                    // save the source model, source/target differences,  
                    // and the beginning of the deployment plan.  
                    _sourceModel = context.Source;  
                    _diff = context.ComparisonResult;  
                    _planHead = context.PlanHandle.Head;  
                }  
                /// <summary>  
                /// Property indicating whether script bodies  
                /// should be included in the report.  
                /// </summary>  
                public bool IncludeScripts { get; set; }  
    
                /// <summary>  
                /// Drives the report generation, opening files,   
                /// writing the beginning and ending report elements,  
                /// and calling helper methods to report on the  
                /// plan operations.  
                /// </summary>  
                internal void WriteReport(FileInfo reportFile)  
                {// Assumes that we have a valid report file  
                    if (reportFile == null)  
                    {  
                        throw new ArgumentNullException("reportFile");  
                    }  
    
                    // set up the XML writer  
                    XmlWriterSettings xmlws = new XmlWriterSettings();  
                    // Indentation makes it a bit more readable  
                    xmlws.Indent = true;  
                    FileStream fs = new FileStream(reportFile.FullName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);  
                    XmlWriter xmlw = XmlWriter.Create(fs, xmlws);  
    
                    try  
                    {  
                        xmlw.WriteStartDocument(true);  
                        xmlw.WriteStartElement("DeploymentReport");  
    
                        // Summary report of the operations that  
                        // are contained in the plan.  
                        ReportPlanOperations(xmlw);  
    
                        // You could add a method call here  
                        // to produce a detailed listing of the   
                        // differences between the source and  
                        // target model.  
                        xmlw.WriteEndElement();  
                        xmlw.WriteEndDocument();  
                        xmlw.Flush();  
                        fs.Flush();  
                    }  
                    finally  
                    {  
                        xmlw.Close();  
                        fs.Dispose();  
                    }  
                }  
    
                /// <summary>  
                /// Writes details for the various operation types  
                /// that could be contained in the deployment plan.  
                /// Optionally writes script bodies, depending on  
                /// the value of the IncludeScripts property.  
                /// </summary>  
                private void ReportPlanOperations(XmlWriter xmlw)  
                {// write the node to indicate the start  
                    // of the list of operations.  
                    xmlw.WriteStartElement("Operations");  
    
                    // Loop through the steps in the plan,  
                    // starting at the beginning.  
                    DeploymentStep currentStep = _planHead;  
                    while (currentStep != null)  
                    {  
                        // Report the type of step  
                        xmlw.WriteStartElement(currentStep.GetType().Name);  
    
                        // based on the type of step, report  
                        // the relevant information.  
                        // Note that this procedure only handles   
                        // a subset of all step types.  
                        if (currentStep is SqlRenameStep)  
                        {  
                            SqlRenameStep renameStep = (SqlRenameStep)currentStep;  
                            xmlw.WriteAttributeString("OriginalName", renameStep.OldName);  
                            xmlw.WriteAttributeString("NewName", renameStep.NewName);  
                            xmlw.WriteAttributeString("Category", GetElementCategory(renameStep.RenamedElement));  
                        }  
                        else if (currentStep is SqlMoveSchemaStep)  
                        {  
                            SqlMoveSchemaStep moveStep = (SqlMoveSchemaStep)currentStep;  
                            xmlw.WriteAttributeString("OriginalName", moveStep.PreviousName);  
                            xmlw.WriteAttributeString("NewSchema", moveStep.NewSchema);  
                            xmlw.WriteAttributeString("Category", GetElementCategory(moveStep.MovedElement));  
                        }  
                        else if (currentStep is SqlTableMigrationStep)  
                        {  
                            SqlTableMigrationStep dmStep = (SqlTableMigrationStep)currentStep;  
                            xmlw.WriteAttributeString("Name", GetElementName(dmStep.SourceTable));  
                            xmlw.WriteAttributeString("Category", GetElementCategory(dmStep.SourceElement));  
                        }  
                        else if (currentStep is CreateElementStep)  
                        {  
                            CreateElementStep createStep = (CreateElementStep)currentStep;  
                            xmlw.WriteAttributeString("Name", GetElementName(createStep.SourceElement));  
                            xmlw.WriteAttributeString("Category", GetElementCategory(createStep.SourceElement));  
                        }  
                        else if (currentStep is AlterElementStep)  
                        {  
                            AlterElementStep alterStep = (AlterElementStep)currentStep;  
                            xmlw.WriteAttributeString("Name", GetElementName(alterStep.SourceElement));  
                            xmlw.WriteAttributeString("Category", GetElementCategory(alterStep.SourceElement));  
                        }  
                        else if (currentStep is DropElementStep)  
                        {  
                            DropElementStep dropStep = (DropElementStep)currentStep;  
                            xmlw.WriteAttributeString("Name", GetElementName(dropStep.TargetElement));  
                            xmlw.WriteAttributeString("Category", GetElementCategory(dropStep.TargetElement));  
                        }  
    
                        // If the script bodies are to be included,  
                        // add them to the report.  
                        if (this.IncludeScripts)  
                        {  
                            using (StringWriter sw = new StringWriter())  
                            {  
                                currentStep.GenerateBatchScript(sw);  
                                string tsqlBody = sw.ToString();  
                                if (string.IsNullOrEmpty(tsqlBody) == false)  
                                {  
                                    xmlw.WriteCData(tsqlBody);  
                                }  
                            }  
                        }  
    
                        // close off the current step  
                        xmlw.WriteEndElement();  
                        currentStep = currentStep.Next;  
                    }  
                    xmlw.WriteEndElement();  
                }  
    
                /// <summary>  
                /// Returns the category of the specified element  
                /// in the source model  
                /// </summary>  
                private string GetElementCategory(TSqlObject element)  
                {  
                    return element.ObjectType.Name;  
                }  
    
                /// <summary>  
                /// Returns the name of the specified element  
                /// in the source model  
                /// </summary>  
                private static string GetElementName(TSqlObject element)  
                {  
                    StringBuilder name = new StringBuilder();  
                    if (element.Name.HasExternalParts)  
                    {  
                        foreach (string part in element.Name.ExternalParts)  
                        {  
                            if (name.Length > 0)  
                            {  
                                name.Append('.');  
                            }  
                            name.AppendFormat("[{0}]", part);  
                        }  
                    }  
    
                    foreach (string part in element.Name.Parts)  
                    {  
                        if (name.Length > 0)  
                        {  
                            name.Append('.');  
                        }  
                        name.AppendFormat("[{0}]", part);  
                    }  
    
                    return name.ToString();  
                }  
            }        /// <summary>  
            /// This class is used to generate a deployment  
            /// report.   
            /// </summary>  
            private class DeploymentReportWriter  
            {  
                /// <summary>  
                /// The constructor accepts the same context info  
                /// that was passed to the OnExecute method of the  
                /// deployment contributor.  
                /// </summary>  
                public DeploymentReportWriter(DeploymentPlanContributorContext context)  
                {  
               }  
                /// <summary>  
                /// Property indicating whether script bodies  
                /// should be included in the report.  
                /// </summary>  
                public bool IncludeScripts { get; set; }  
    
                /// <summary>  
                /// Drives the report generation, opening files,   
                /// writing the beginning and ending report elements,  
                /// and calling helper methods to report on the  
                /// plan operations.  
                /// </summary>  
                internal void WriteReport(FileInfo reportFile)  
                {  
                }  
    
                /// <summary>  
                /// Writes details for the various operation types  
                /// that could be contained in the deployment plan.  
                /// Optionally writes script bodies, depending on  
                /// the value of the IncludeScripts property.  
                /// </summary>  
                private void ReportPlanOperations(XmlWriter xmlw)  
                {  
                }  
    
                /// <summary>  
                /// Returns the category of the specified element  
                /// in the source model  
                /// </summary>  
                private string GetElementCategory(IModelElement element)  
                {  
                }  
    
                /// <summary>  
                /// Returns the name of the specified element  
                /// in the source model  
                /// </summary>  
                private string GetElementName(IModelElement element)  
                {  
                }  
            }  
    
  • Zapisz zmiany w pliku klasy. W klasie pomocniczej odwołuje się wiele przydatnych typów:

    obszaru kodu przydatne typy
    Składowe klasy TSqlModel, ModelComparisonResult, DeploymentStep
    Metoda WriteReport XmlWriter i XmlWriterSettings
    ReportPlanOperations metoda Oto następujące typy zainteresowań: DeploymentStep, SqlRenameStep, SqlMoveSchemaStep, SqlTableMigrationStep, CreateElementStep, AlterElementStep, DropElementStep.

    Istnieje wiele innych kroków — zapoznaj się z dokumentacją interfejsu API, aby uzyskać pełną listę kroków.
    GetElementCategory TSqlObject
    PobierzNazwęElementu TSqlObject

    Następnie utworzysz bibliotekę klas.

Aby podpisać i skompilować zestaw

  1. W menu Project kliknij opcję MyDeploymentContributor Properties.

  2. Kliknij kartę podpisywania.

  3. Kliknij , aby podpisać zestaw.

  4. W Wybierz plik klucza silnej nazwykliknij <Nowy>.

  5. W oknie dialogowym Utwórz silny klucz nazwy w Nazwa pliku kluczawpisz MyRefKey.

  6. (opcjonalnie) Możesz określić hasło dla pliku klucza o silnej nazwie.

  7. Kliknij przycisk OK.

  8. W menu Plik kliknij pozycję Zapisz wszystkie.

  9. W menu Kompilacja kliknij pozycję Kompiluj rozwiązanie.

Następnie należy zainstalować zestaw, aby był ładowany podczas kompilowania i wdrażania projektów SQL.

Instalowanie współautora wdrożenia

Aby zainstalować współautora wdrożenia, należy skopiować zestaw i skojarzony plik .pdb do folderu Extensions.

Aby zainstalować zestaw MyDeploymentContributor

  • Następnie skopiujesz informacje o zestawie do katalogu Extensions. Po uruchomieniu programu Visual Studio zidentyfikuje wszelkie rozszerzenia w %Program Files%\Microsoft SQL Server\110\DAC\Bin\Extensions katalogu i podkatalogów oraz udostępni je do użycia:

  • Skopiuj plik zestawu MyDeploymentContributor.dll z katalogu wyjściowego do katalogu %Program Files%\Microsoft SQL Server\110\DAC\Bin\Extensions. Domyślnie ścieżka skompilowanego pliku .dll to YourSolutionPath\YourProjectPath\bin\Debug lub YourSolutionPath\YourProjectPath\bin\Release.

Sprawdź swojego kontrybutora wdrożenia

Aby przetestować współautora wdrożenia, należy wykonać następujące zadania:

  • Dodaj właściwości do pliku sqlproj, który planujesz wdrożyć.

  • Wdróż projekt przy użyciu programu MSBuild i podaj odpowiedni parametr.

Dodawanie właściwości do pliku projektu SQL (sqlproj)

Należy zawsze zaktualizować plik projektu SQL, aby określić identyfikator współautorów, których chcesz uruchomić. Ponadto, ponieważ ten współautor oczekuje argumentu "GenerateUpdateReport", który musi zostać określony jako argument współautora.

Można to zrobić na jeden z dwóch sposobów. Możesz ręcznie zmodyfikować plik .sqlproj, aby dodać wymagane argumenty. Możesz to zrobić, jeśli współautor nie ma żadnych argumentów współautora wymaganych do konfiguracji lub jeśli nie zamierzasz ponownie używać współautora w dużej liczbie projektów. Jeśli wybierzesz tę opcję, dodaj następujące instrukcje do pliku .sqlproj po pierwszym elemencie Import w pliku:

<PropertyGroup>  
    <DeploymentContributors>$(DeploymentContributors); MyDeploymentContributor.DeploymentUpdateReportContributor</DeploymentContributors>  
<ContributorArguments Condition="'$(Configuration)' == 'Debug'">$(ContributorArguments);DeploymentUpdateReportContributor.GenerateUpdateReport=true;</ContributorArguments>  
  </PropertyGroup>  

Druga metoda polega na utworzeniu pliku targets zawierającego wymagane argumenty współautora. Jest to przydatne, jeśli używasz tego samego współautora dla wielu projektów i masz wymagane argumenty współautora, ponieważ będzie zawierać wartości domyślne. W takim przypadku utwórz plik targets w ścieżce rozszerzeń MSBuild.

  1. Przejdź do %Program Files%\MSBuild.

  2. Utwórz nowy folder "MyContributors", w którym będą przechowywane pliki docelowe.

  3. Utwórz nowy plik "MyContributors.targets" w tym katalogu, dodaj do niego następujący tekst i zapisz plik:

    <?xml version="1.0" encoding="utf-8"?>  
    
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  
      <PropertyGroup>  
    <DeploymentContributors>$(DeploymentContributors);MyDeploymentContributor.DeploymentUpdateReportContributor</DeploymentContributors>  
    <ContributorArguments Condition="'$(Configuration)' == 'Debug'">$(ContributorArguments); DeploymentUpdateReportContributor.GenerateUpdateReport=true;</ContributorArguments>  
      </PropertyGroup>  
    </Project>  
    
  4. Wewnątrz pliku .sqlproj dla dowolnego projektu, w którym chcesz uruchomić współautorów, zaimportuj plik targets, dodając następującą instrukcję do pliku .sqlproj po węźle <: Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets" / węzłem>:

    <Import Project="$(MSBuildExtensionsPath)\MyContributors\MyContributors.targets " />  
    

Po zastosowaniu jednego z tych podejść możesz użyć programu MSBuild do przekazywania parametrów kompilacji wiersza polecenia.

Notatka

Aby określić identyfikator współautora, należy zawsze zaktualizować właściwość "DeploymentContributors". Jest to ten sam identyfikator używany w atrybucie "ExportDeploymentPlanExecutor" w pliku źródłowym współautora. Bez tego twój wkład nie będzie wykonywany podczas kompilowania projektu. Właściwość "ContributorArguments" musi zostać zaktualizowana tylko wtedy, gdy masz argumenty wymagane do uruchomienia przez współautora.

Wdrażanie projektu bazy danych

Projekt można opublikować lub wdrożyć w zwykły sposób w programie Visual Studio. Wystarczy otworzyć rozwiązanie zawierające projekt SQL i wybrać opcję "Publikuj..." z menu kontekstowego projektu dostępnego po kliknięciu prawym przyciskiem myszy, lub użyć F5 do debugowania wdrożenia do LocalDB. W tym przykładzie użyjemy polecenia "Publikuj..." okno dialogowe w celu wygenerowania skryptu wdrożenia.

Aby wdrożyć projekt SQL i wygenerować raport wdrożenia
  1. Otwórz program Visual Studio i otwórz rozwiązanie zawierające projekt SQL.

  2. Wybierz projekt i naciśnij F5, aby przeprowadzić wdrożenie debugowania. Uwaga: ponieważ element ContributorArguments jest ustawiony na uwzględnianie tylko wtedy, gdy konfiguracja to "Debug", na razie raport wdrożenia jest generowany tylko dla wdrożeń debug. Aby to zmienić, usuń instrukcję Condition="$(Configuration)" == 'Debug'" z definicji ContributorArguments.

  3. Dane wyjściowe, takie jak następujące, powinny być obecne w oknie danych wyjściowych:

    ------ Deploy started: Project: Database1, Configuration: Debug Any CPU ------  
    Finished verifying cached model in 00:00:00  
    Deployment reports ->  
    
      C:\Users\UserName\Documents\Visual Studio 2012\Projects\MyDatabaseProject\MyDatabaseProject\sql\debug\MyTargetDatabase.summary.xml  
      C:\Users\UserName\Documents\Visual Studio 2012\Projects\MyDatabaseProject\MyDatabaseProject\sql\debug\MyTargetDatabase.details.xml  
    
      Deployment script generated to:  
      C:\Users\UserName\Documents\Visual Studio 2012\Projects\MyDatabaseProject\MyDatabaseProject\sql\debug\MyDatabaseProject.sql  
    
    
  4. Otwórz MyTargetDatabase.summary.xml i sprawdź zawartość. Plik przypomina następujący przykład pokazujący nowe wdrożenie bazy danych:

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>  
    <DeploymentReport>  
      <Operations>  
        <DeploymentScriptStep />  
        <DeploymentScriptDomStep />  
        <DeploymentScriptStep />  
        <DeploymentScriptDomStep />  
        <DeploymentScriptStep />  
        <DeploymentScriptStep />  
        <DeploymentScriptStep />  
        <DeploymentScriptStep />  
        <DeploymentScriptDomStep />  
        <DeploymentScriptDomStep />  
        <DeploymentScriptDomStep />  
        <DeploymentScriptDomStep />  
        <DeploymentScriptStep />  
        <DeploymentScriptDomStep />  
        <BeginPreDeploymentScriptStep />  
        <DeploymentScriptStep />  
        <EndPreDeploymentScriptStep />  
        <SqlBeginPreservationStep />  
        <SqlEndPreservationStep />  
        <SqlBeginDropsStep />  
        <SqlEndDropsStep />  
        <SqlBeginAltersStep />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales" Category="Schema" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.Customer" Category="Table" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.PK_Customer_CustID" Category="Primary Key" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.Orders" Category="Table" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.PK_Orders_OrderID" Category="Primary Key" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.Def_Customer_YTDOrders" Category="Default Constraint" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.Def_Customer_YTDSales" Category="Default Constraint" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.Def_Orders_OrderDate" Category="Default Constraint" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.Def_Orders_Status" Category="Default Constraint" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.FK_Orders_Customer_CustID" Category="Foreign Key" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.CK_Orders_FilledDate" Category="Check Constraint" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.CK_Orders_OrderDate" Category="Check Constraint" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.uspCancelOrder" Category="Procedure" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.uspFillOrder" Category="Procedure" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.uspNewCustomer" Category="Procedure" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.uspPlaceNewOrder" Category="Procedure" />  
        <SqlPrintStep />  
        <CreateElementStep Name="Sales.uspShowOrderDetails" Category="Procedure" />  
        <SqlEndAltersStep />  
        <DeploymentScriptStep />  
        <BeginPostDeploymentScriptStep />  
        <DeploymentScriptStep />  
        <EndPostDeploymentScriptStep />  
        <DeploymentScriptDomStep />  
        <DeploymentScriptDomStep />  
        <DeploymentScriptDomStep />  
      </Operations>  
    </DeploymentReport>  
    
    

    Notatka

    W przypadku wdrożenia projektu bazy danych identycznego z docelową bazą danych wynikowy raport nie będzie bardzo znaczący. Aby uzyskać bardziej znaczące wyniki, wdróż zmiany w bazie danych lub wdróż nową bazę danych.

  5. Otwórz MyTargetDatabase.details.xml i sprawdź zawartość. W małej sekcji pliku szczegółów znajdują się wpisy i skrypty, które tworzą schemat Sales, wyświetlają komunikat o tworzeniu tabeli i tworzą tabelę.

    <CreateElementStep Name="Sales" Category="Schema"><![CDATA[CREATE SCHEMA [Sales]  
        AUTHORIZATION [dbo];  
    
    ]]></CreateElementStep>  
        <SqlPrintStep><![CDATA[PRINT N'Creating [Sales].[Customer]...';  
    
    ]]></SqlPrintStep>  
        <CreateElementStep Name="Sales.Customer" Category="Table"><![CDATA[CREATE TABLE [Sales].[Customer] (  
        [CustomerID]   INT           IDENTITY (1, 1) NOT NULL,  
        [CustomerName] NVARCHAR (40) NOT NULL,  
        [YTDOrders]    INT           NOT NULL,  
        [YTDSales]     INT           NOT NULL  
    );  
    
    ]]></CreateElementStep>  
    
    

    Analizując plan wdrożenia podczas jego wykonywania, można zgłosić wszelkie informacje zawarte we wdrożeniu i wykonać dodatkowe akcje na podstawie kroków w tym planie.

Następne kroki

Możesz utworzyć dodatkowe narzędzia do przetwarzania wyjściowych plików XML. Jest to tylko jeden przykład DeploymentPlanExecutor. Można również utworzyć DeploymentPlanModifier, aby zmienić plan wdrożenia przed jego wykonaniem.

Zobacz też

przewodnik : rozszerzanie kompilacji projektu bazy danych w celu generowania statystyk modelu
przewodnik : rozszerzanie wdrożenia projektu bazy danych w celu zmodyfikowania planu wdrożenia
dostosowywanie kompilacji i wdrażania bazy danych przy użyciu współautorów kompilacji i wdrażania