Condividi tramite


Procedura dettagliata: Estendere la distribuzione del progetto di database per analizzare il piano di distribuzione

È possibile creare collaboratori alla distribuzione per eseguire azioni personalizzate quando si distribuisce un progetto SQL. È possibile creare un DeploymentPlanModifier o un DeploymentPlanExecutor. Usare DeploymentPlanModifier per modificare il piano prima dell'esecuzione e un DeploymentPlanExecutor per eseguire operazioni durante l'esecuzione del piano. In questa procedura dettagliata viene creato un DeploymentPlanExecutor denominato DeploymentUpdateReportContributor che crea un report sulle azioni eseguite quando si distribuisce un progetto di database. Poiché questo collaboratore alla compilazione accetta un parametro per controllare se il report viene generato, è necessario eseguire un altro passaggio obbligatorio.

In questa procedura dettagliata vengono eseguite le attività principali seguenti:

Prerequisiti

Per completare questa procedura dettagliata sono necessari i componenti seguenti:

  • È necessario aver installato una versione di Visual Studio che include SQL Server Data Tools (SSDT) e supporta lo sviluppo in C# o VB.
  • È necessario disporre di un progetto SQL che contiene oggetti SQL.
  • Istanza di SQL Server in cui è possibile distribuire un progetto di database.

Nota

Questa procedura dettagliata è destinata agli utenti che hanno già familiarità con le funzionalità SQL di SSDT. Si prevede anche di avere familiarità con i concetti di base di Visual Studio, ad esempio come creare una libreria di classi e come usare l'editor di codice per aggiungere codice a una classe.

Creare un collaboratore alla distribuzione

Per creare un collaboratore alla distribuzione, è necessario eseguire le attività seguenti:

  • Creare un progetto di libreria di classi e aggiungere i riferimenti necessari.

  • Definire una classe denominata DeploymentUpdateReportContributor che eredita da DeploymentPlanExecutor.

  • Sovrascrivere il metodo OnExecute.

  • Aggiungere una classe helper privata.

  • Compilare l'assemblaggio risultante.

Creare un progetto di libreria di classi

  1. Creare un progetto di libreria di classi Visual Basic o C# denominato MyDeploymentContributor.

  2. Rinominare il file "Class1.cs" in "DeploymentUpdateReportContributor.cs".

  3. In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo del progetto e quindi scegliere Aggiungi riferimento.

  4. Selezionare System.ComponentModel.Composition nella scheda Framework.

  5. Aggiungere i riferimenti SQL necessari: fare clic con il pulsante destro del mouse sul nodo del progetto e quindi scegliere Aggiungi riferimento. Selezionare Sfoglia e passare alla cartella C:\Programmi (x86)\Microsoft SQL Server\110\DAC\Bin . Scegliere Microsoft.SqlServer.Dac.dll, Microsoft.SqlServer.Dac.Extensions.dll e Microsoft.Data.Tools.Schema.Sql.dll, selezionare Aggiungi e quindi OK.

    Iniziare quindi ad aggiungere codice alla classe .

Definire la classe DeploymentUpdateReportContributor

  1. Nell'editor di codice aggiornare il file di DeploymentUpdateReportContributor.cs in modo che corrisponda alle seguenti usando istruzioni:

    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. Aggiornare la definizione della classe in modo che corrisponda al codice seguente:

    /// <summary>
        /// An executor that generates a report detailing the steps in the deployment plan. Only runs 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:
        ///
        /// <PropertyGroup>
        ///     <ContributorArguments Condition="'$(Configuration)' == 'Debug'">
        /// $(ContributorArguments);DeploymentUpdateReportContributor.GenerateUpdateReport=true;
        ///     </ContributorArguments>
        /// <PropertyGroup>
        ///
        /// </summary>
        [ExportDeploymentPlanExecutor("MyDeploymentContributor.DeploymentUpdateReportContributor", "1.0.0.0")]
        public class DeploymentUpdateReportContributor : DeploymentPlanExecutor
        {
        }
    

    Ora hai definito il contributore di distribuzione che eredita da DeploymentPlanExecutor. Durante i processi di compilazione e distribuzione, i contributori personalizzati vengono caricati da una directory standard di estensione. I collaboratori dell'esecutore del piano di distribuzione sono identificati da un attributo ExportDeploymentPlanExecutor.

    Questo attributo è obbligatorio in modo che i collaboratori possano essere individuati. Dovrebbe essere simile al codice seguente:

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

    In questo caso il primo parametro dell'attributo deve essere un identificatore univoco, usato per identificare il collaboratore nei file di progetto. Una buona pratica consiste nel combinare lo spazio dei nomi della libreria, in questa guida MyDeploymentContributor, con il nome della classe, DeploymentUpdateReportContributor, per produrre l'identificatore.

  3. Aggiungere quindi il membro seguente usato per consentire a questo provider di accettare un parametro della riga di comando:

    public const string GenerateUpdateReport = "DeploymentUpdateReportContributor.GenerateUpdateReport";
    

    Questo membro consente all'utente di specificare se il report deve essere generato utilizzando l'opzione GenerateUpdateReport.

    Eseguire quindi l'override del metodo OnExecute per aggiungere il codice da eseguire quando viene distribuito un progetto di database.

Eseguire l'override di OnExecute

  • Aggiungere il metodo seguente alla classe 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 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 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);
            }
    

    Al metodo OnExecute viene passato un oggetto DeploymentPlanContributorContext che fornisce l'accesso a qualsiasi argomento specificato, al modello di database di origine e di destinazione, alle proprietà di compilazione e ai file di estensione. In questo esempio si ottiene il modello e quindi si chiamano le funzioni helper per restituire informazioni sul modello. Per segnalare eventuali errori che si verificano, viene usato il metodo helper PublishMessage nella classe di base.

    Altri tipi e metodi di interesse includono: TSqlModel, ModelComparisonResult, DeploymentPlanHandlee SqlDeploymentOptions.

    Successivamente, si definisce la classe helper che consente di esaminare i dettagli del piano di distribuzione.

Aggiungere la classe helper che genera il corpo del report

  • Aggiungere la classe helper e i relativi metodi aggiungendo il codice seguente:

    /// <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)
                {
                }
            }
    
  • Salvare le modifiche apportate al file di classe. Nella classe helper viene fatto riferimento a diversi tipi utili:

    Area di codice Tipi utili
    Membri della classe TSqlModel, ModelComparisonResult, DeploymentStep
    Metodo WriteReport XmlWriter e XmlWriterSettings
    Metodo ReportPlanOperations I tipi di interesse includono: DeploymentStep, SqlRenameStep, SqlMoveSchemaStep, SqlTableMigrationStep, CreateElementStep, AlterElementStep, DropElementStep.

    Esistono diversi altri passaggi: vedere la documentazione dell'API per un elenco completo dei passaggi.
    GetElementCategory TSqlObject
    GetElementName TSqlObject

    Successivamente, si costruisce la libreria di classi.

Firmare e compilare l'assembly

  1. Nel menu Progetto, selezionare Proprietà di MyDeploymentContributor.

  2. Selezionare la scheda Firma .

  3. Selezionare Firma l'assembly.

  4. In Scegliere un file di chiave con nome sicuro selezionare <Nuovo>.

  5. Nella finestra di dialogo Crea chiave con nome sicuro digitare in Nome file chiaveMyRefKey .

  6. (facoltativo) È possibile specificare una password per il file di chiave con nome sicuro.

  7. Seleziona OK.

  8. Scegliere Salva tutto dal menu File.

  9. Scegliere Compila soluzione dal menu Compila.

Successivamente, è necessario installare l'assembly in modo che venga caricato quando si compilano e si distribuiscono progetti SQL.

Installare un collaboratore alla distribuzione

Per installare un collaboratore alla distribuzione, è necessario copiare l'assembly e il file associato .pdb nella cartella Estensioni.

Installare l'assembly MyDeploymentContributor

  • Copia quindi le informazioni sull'assembly nella directory Extensions. All'avvio di Visual Studio, identifica le estensioni nella %ProgramFiles%\Microsoft SQL Server\110\DAC\Bin\Extensions directory e nelle sottodirectory e le rende disponibili per l'uso:

  • Copiare il MyDeploymentContributor.dll file di assembly dalla directory di output nella %ProgramFiles%\Microsoft SQL Server\110\DAC\Bin\Extensions directory . Per impostazione predefinita, il percorso del file compilato .dll è YourSolutionPath\YourProjectPath\bin\Debug o YourSolutionPath\YourProjectPath\bin\Release.

Testare il collaboratore alla distribuzione

Per testare il collaboratore alla distribuzione, è necessario eseguire le attività seguenti:

  • Aggiungere proprietà al .sqlproj file che si prevede di distribuire.

  • Distribuire il progetto usando MSBuild e specificando il parametro appropriato.

Aggiungere proprietà al file di progetto SQL (con estensione sqlproj)

È necessario aggiornare sempre il file di progetto SQL per specificare l'ID dei collaboratori da eseguire. Inoltre, poiché questo collaboratore si aspetta un argomento "GenerateUpdateReport", questo deve essere specificato come argomento del collaboratore.

È possibile eseguire questa operazione in uno dei due modi seguenti. È possibile modificare manualmente il .sqlproj file per aggiungere gli argomenti necessari. È possibile scegliere di eseguire questa operazione se il collaboratore non ha argomenti necessari per la configurazione, o se non si intende riutilizzare il collaboratore su un'ampia gamma di progetti. Se si sceglie questa opzione, aggiungere le istruzioni seguenti al .sqlproj file dopo il primo nodo Import nel file:

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

Il secondo metodo consiste nel creare un file targets contenente gli argomenti richiesti dei collaboratori. Ciò è utile se si usa lo stesso collaboratore per più progetti e si hanno argomenti di collaboratore necessari, poiché include i valori predefiniti. In questo caso, creare un file di destinazioni nel percorso delle estensioni MSBuild.

  1. Navigare verso %ProgramFiles%\MSBuild.

  2. Creare una nuova cartella MyContributors in cui sono archiviati i file di destinazione.

  3. Creare un nuovo file MyContributors.targets all'interno di questa directory, aggiungere il testo seguente e salvare il file:

    <?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. All'interno del file .sqlproj per qualsiasi progetto che si desidera eseguire, importare il file targets aggiungendo la seguente istruzione al file .sqlproj dopo il nodo <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets" /> nel file:

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

Dopo aver seguito uno di questi approcci, è possibile usare MSBuild per passare i parametri per le compilazioni della riga di comando.

Nota

È necessario aggiornare sempre la proprietà "DeploymentContributors" per specificare l'ID collaboratore. Si tratta dello stesso ID usato nell'attributo "ExportDeploymentPlanExecutor" nel file sorgente del contributore. Senza questo il contributore non viene eseguito durante la fase di build del progetto. La proprietà "ContributorArguments" deve essere aggiornata solo se sono necessari argomenti richiesti affinché il tuo contributore funzioni.

Distribuire il progetto del database

Il progetto può essere pubblicato o distribuito normalmente all'interno di Visual Studio. Aprire una soluzione contenente il progetto SQL e scegliere "Pubblica..." dal menu di scelta rapida del pulsante destro del mouse per il progetto oppure usare F5 per una distribuzione di debug in LocalDB. In questo esempio viene usato "Publish..." finestra di dialogo per generare uno script di distribuzione.

Distribuire il progetto SQL e generare un report di distribuzione

  1. Aprire Visual Studio e aprire la soluzione contenente il progetto SQL.

  2. Selezionare il progetto e premere "F5" per eseguire una distribuzione di debug. Nota: poiché l'elemento ContributorArguments è impostato su essere incluso solo se la configurazione è "Debug", per il momento il report di distribuzione viene generato solo per le distribuzioni di debug. Per modificare questa operazione, rimuovere l'istruzione Condition="'$(Configuration)' == 'Debug'" dalla definizione ContributorArguments.

  3. L'output, ad esempio l'esempio seguente, deve essere presente nella finestra di output:

    ------ 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. Aprire MyTargetDatabase.summary.xml ed esaminare il contenuto. Il file è simile all'esempio seguente che mostra una nuova distribuzione del database:

    <?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>
    

    Nota

    Se si distribuisce un progetto di database identico al database di destinazione, il report risultante non è molto significativo. Per risultati più significativi, distribuire le modifiche in un database o distribuire un nuovo database.

  5. Aprire MyTargetDatabase.details.xml ed esaminare il contenuto. Una piccola sezione del file dei dettagli mostra le voci e lo script che creano lo schema Sales, che stampano un messaggio sulla creazione di una tabella e che creano la tabella:

    <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>
    

    Analizzando il piano di distribuzione durante l'esecuzione, è possibile segnalare tutte le informazioni contenute nella distribuzione e possono eseguire altre azioni in base ai passaggi di tale piano.