Distribuzione delle appartenenze ai ruoli del database negli ambienti di test

di Jason Lee

Questo argomento descrive come aggiungere account utente ai ruoli del database come parte di una distribuzione di soluzioni in un ambiente di test.

Quando si distribuisce una soluzione contenente un progetto di database in un ambiente di gestione temporanea o di produzione, in genere lo sviluppatore non vuole automatizzare l'aggiunta di account utente ai ruoli del database. Nella maggior parte dei casi, lo sviluppatore non saprà quali account utente devono essere aggiunti ai ruoli del database e questi requisiti potrebbero cambiare in qualsiasi momento. Tuttavia, quando si distribuisce una soluzione contenente un progetto di database in un ambiente di sviluppo o test, la situazione è in genere piuttosto diversa:

  • Lo sviluppatore in genere distribuisce di nuovo la soluzione a intervalli regolari, spesso più volte al giorno.
  • Il database viene in genere ricreato in ogni distribuzione, il che significa che gli utenti del database devono essere creati e aggiunti ai ruoli dopo ogni distribuzione.
  • Lo sviluppatore ha in genere il controllo completo sull'ambiente di sviluppo o test di destinazione.

In questo scenario, spesso è utile creare automaticamente utenti del database e assegnare appartenenze ai ruoli del database come parte del processo di distribuzione.

Il fattore chiave è che questa operazione deve essere condizionale in base all'ambiente di destinazione. Se si esegue la distribuzione in un ambiente di staging o di produzione, si vuole ignorare l'operazione. Se si esegue la distribuzione in un ambiente di sviluppo o test, si vuole distribuire le appartenenze ai ruoli senza ulteriori interventi. Questo argomento descrive un approccio che è possibile usare per risolvere questa sfida.

Questo argomento fa parte di una serie di esercitazioni basate sui requisiti di distribuzione aziendali di una società fittizia denominata Fabrikam, Inc. Questa serie di esercitazioni usa una soluzione di esempio, la soluzione Contact Manager, per rappresentare un'applicazione Web con un livello realistico di complessità, tra cui un'applicazione ASP.NET MVC 3, un servizio Windows Communication Foundation (WCF) e un progetto di database.

Il metodo di distribuzione al centro di queste esercitazioni si basa sull'approccio split project file descritto in Informazioni sul file di progetto, in cui il processo di compilazione è controllato da due file di progetto, uno contenente le istruzioni di compilazione applicabili a ogni ambiente di destinazione e uno contenente le impostazioni di compilazione e distribuzione specifiche dell'ambiente. In fase di compilazione, il file di progetto specifico dell'ambiente viene unito al file di progetto indipendente dall'ambiente per formare un set completo di istruzioni di compilazione.

Panoramica delle attività

In questo argomento si presuppone che l'utente:

Per creare utenti del database e assegnare appartenenze ai ruoli quando si distribuisce un progetto di database in un ambiente di test, è necessario:

  • Creare uno script Transact Structured Query Language (Transact-SQL) che apporta le modifiche necessarie al database.
  • Creare una destinazione Microsoft Build Engine (MSBuild) che usa l'utilità sqlcmd.exe per eseguire lo script SQL.
  • Configurare i file di progetto per richiamare la destinazione quando si distribuisce la soluzione in un ambiente di test.

In questo argomento viene illustrato come eseguire ognuna di queste procedure.

Creazione di script per le appartenenze ai ruoli del database

È possibile creare uno script Transact-SQL in molti modi diversi e in qualsiasi posizione scelta. L'approccio più semplice consiste nel creare lo script all'interno della soluzione in Visual Studio 2010.

Per creare uno script SQL

  1. Nella finestra Esplora soluzioni espandere il nodo del progetto di database.

  2. Fare clic con il pulsante destro del mouse sulla cartella Scripts , scegliere Aggiungi e quindi fare clic su Nuova cartella.

  3. Digitare Test come nome della cartella e quindi premere INVIO.

  4. Fare clic con il pulsante destro del mouse sulla cartella Test , scegliere Aggiungi e quindi fare clic su Script.

  5. Nella finestra di dialogo Aggiungi nuovo elemento assegnare allo script un nome significativo , ad esempio AddRoleMemberships.sql, quindi fare clic su Aggiungi.

    Nella finestra di dialogo Aggiungi nuovo elemento assegnare allo script un nome significativo , ad esempio AddRoleMemberships.sql, quindi fare clic su Aggiungi.

  6. Nel file AddRoleMemberships.sql aggiungere istruzioni Transact-SQL che:

    1. Creare un utente del database per l'account di accesso SQL Server che accederà al database.
    2. Aggiungere l'utente del database a tutti i ruoli del database necessari.
  7. Il file dovrebbe essere simile al seguente:

    USE $(DatabaseName)
    GO
    CREATE USER [FABRIKAM\TESTWEB1$] FOR LOGIN[FABRIKAM\TESTWEB1$]
    GO
    USE [ContactManager]
    GO
    EXEC sp_addrolemember N'db_datareader', N'FABRIKAM\TESTWEB1$'
    GO
    USE [ContactManager]
    GO
    EXEC sp_addrolemember N'db_datawriter', N'FABRIKAM\TESTWEB1$'
    GO
    
  8. Salvare il file.

Esecuzione dello script nel database di destinazione

Idealmente, è possibile eseguire tutti gli script Transact-SQL necessari come parte di uno script post-distribuzione quando si distribuisce il progetto di database. Tuttavia, gli script post-distribuzione non consentono di eseguire la logica in modo condizionale in base alle configurazioni della soluzione o alle proprietà di compilazione. L'alternativa consiste nell'eseguire gli script SQL direttamente dal file di progetto MSBuild, creando un elemento Target che esegue un comando sqlcmd.exe. È possibile usare questo comando per eseguire lo script nel database di destinazione:

sqlcmd.exe –S [Database server] –d [Database name] –i [SQL script]

Nota

Per altre informazioni sulle opzioni della riga di comando di sqlcmd, vedere Utilità sqlcmd.

Prima di incorporare questo comando in una destinazione MSBuild, è necessario considerare in quali condizioni si vuole eseguire lo script:

  • Prima di modificare le appartenenze ai ruoli, è necessario che il database di destinazione esista. Di conseguenza, è necessario eseguire questo script dopo la distribuzione del database.
  • È necessario includere una condizione in modo che lo script venga eseguito solo per gli ambienti di test.
  • Se si esegue una distribuzione "what if", ovvero se si generano script di distribuzione ma non vengono effettivamente eseguiti, non è consigliabile eseguire lo script SQL.

Se si usa l'approccio split project file descritto in Informazioni sul file di progetto, come illustrato dalla soluzione di esempio Contact Manager, è possibile suddividere le istruzioni di compilazione per lo script SQL in questo modo:

  • Tutte le proprietà specifiche dell'ambiente necessarie, insieme alla proprietà che determina se distribuire le autorizzazioni, devono essere incluse nel file di progetto specifico dell'ambiente, ad esempio Env-Dev.proj.
  • La destinazione MSBuild stessa, insieme alle proprietà che non cambieranno tra gli ambienti di destinazione, deve essere inserita nel file di progetto universale( ad esempio Publish.proj).

Nel file di progetto specifico dell'ambiente è necessario definire il nome del server di database, il nome del database di destinazione e una proprietà booleana che consente all'utente di specificare se distribuire le appartenenze ai ruoli.

<PropertyGroup>
   <CmTargetDatabase Condition=" '$(CmTargetDatabase)'=='' ">
      ContactManager
   </CmTargetDatabase>
   <DatabaseServer Condition=" '$(DatabaseServer)'=='' ">
      TESTDB1
   </DatabaseServer>
   <DeployTestDBRoleMemberships Condition="'$(DeployTestDBRoleMemberships)'==''">
      true
   </DeployTestDBRoleMemberships>
</PropertyGroup>

Nel file di progetto universale è necessario specificare il percorso dell'eseguibile sqlcmd e il percorso dello script SQL da eseguire. Queste proprietà rimarranno invariate indipendentemente dall'ambiente di destinazione. È anche necessario creare una destinazione MSBuild per eseguire il comando sqlcmd.

<PropertyGroup>
   <SqlCmdExe Condition=" '$(SqlCmdExe)'=='' ">
      C:\Program Files\Microsoft SQL Server\100\Tools\Binn\sqlcmd.exe
   </SqlCmdExe>
</PropertyGroup>

<Target Name="DeployTestDBPermissions" 
        Condition=" '$(DeployTestDBRoleMemberships)'=='true' AND 
                    '$(Whatif)'!='true' ">
   <PropertyGroup>
     <SqlScript>
        $(SourceRoot)ContactManager.Database\Scripts\Test\AddRoleMemberships.sql
     </SqlScript>
     <_Cmd>"$(SqlCmdExe)" -S "$(DatabaseServer)" 
                          -d "$(CmTargetDatabase)" 
                          -i "$(SqlScript)"
     </_Cmd>
   </PropertyGroup>
   <Exec Command="$(_Cmd)" ContinueOnError="false" />
</Target>

Si noti che si aggiunge il percorso dell'eseguibile sqlcmd come proprietà statica, perché potrebbe essere utile per altre destinazioni. Al contrario, si definisce il percorso dello script SQL e la sintassi del comando sqlcmd come proprietà dinamiche all'interno della destinazione, perché non saranno necessarie prima dell'esecuzione della destinazione. In questo caso, la destinazione DeployTestDBPermissions verrà eseguita solo se vengono soddisfatte queste condizioni:

  • La proprietà DeployTestDBRoleMemberships è impostata su true.
  • L'utente non ha specificato un flag WhatIf=true .

Infine, non dimenticare di richiamare la destinazione. Nel file Publish.proj è possibile eseguire questa operazione aggiungendo la destinazione all'elenco delle dipendenze per la destinazione FullPublish predefinita. È necessario assicurarsi che la destinazione DeployTestDBPermissions non venga eseguita fino a quando non viene eseguita la destinazione PublishDbPackages .

<Project ToolsVersion="4.0" 
         DefaultTargets="FullPublish" 
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   ...
   <PropertyGroup>
      <FullPublishDependsOn>
         Clean;
         BuildProjects;
         GatherPackagesForPublishing;
         PublishDbPackages;
         DeployTestDBPermissions;
         PublishWebPackages;
      </FullPublishDependsOn>
   </PropertyGroup>
   <Target Name="FullPublish" DependsOnTargets="$(FullPublishDependsOn)" />
</Project>

Conclusione

In questo argomento è stato descritto un modo in cui è possibile aggiungere utenti del database e appartenenze ai ruoli come azione post-distribuzione quando si distribuisce un progetto di database. Ciò è in genere utile quando si ricrea regolarmente un database in un ambiente di test, ma in genere è consigliabile evitare quando si distribuiscono i database in ambienti di staging o di produzione. Di conseguenza, è necessario assicurarsi di usare la logica condizionale necessaria in modo che gli utenti e le appartenenze ai ruoli del database vengano creati solo quando è appropriato farlo.

Altre informazioni

Per altre informazioni sull'uso di VSDBCMD per distribuire progetti di database, vedere Distribuzione di progetti di database. Per indicazioni sulla personalizzazione delle distribuzioni di database per ambienti di destinazione diversi, vedere Personalizzazione delle distribuzioni di database per più ambienti. Per altre informazioni sull'uso di file di progetto MSBuild personalizzati per controllare il processo di distribuzione, vedere Informazioni sul file di progetto e Informazioni sul processo di compilazione. Per altre informazioni sulle opzioni della riga di comando di sqlcmd, vedere Utilità sqlcmd.