Roberto Brunetti

ASP.NET - Mobility
Team System

SharePoint Conference

.NET Programming

Corsi

SharePoint

febbraio 2007 - Posts

Corso Team System aggiornato

Da novembre 2006, abbiamo inserito la parte VSTS for DB Pro, nel nostro corso di Visual Studio Team System.

Oggi abbiamo aggiornato anche la scheda tecnica ufficiale, che come sempre viene poi personalizzata in base alle esigenze del cliente finale : http://www.devleap.com/document.aspx?id=3792.

 

Posted: feb 26 2007, 06.19 by rob | with no comments
Filed under:
DevCon 2007 e Sviluppo Mobile

I primi di maggio andrò alla MEDC di Las Vegas dove, fra le altre, si terranno sessioni su Windows Mobile 6.0, .NET CF 3.5 (dovrebbe allinearsi come versione a Orcas).

Le novità sull'SDK per WM 6.0 sono molte ma non stravolgenti; ben più corposo il tema .NET CF 3.5 dove sembra sarà disponibile una versione ridotta di WPF e di Windows Workflow. 

Se vi interessa l'argomento potremmo inserire nello spazio riservato alle sessioni Bonus una sessione sul nuovo SDK e sui nuovi device. Se l'argomento interessa possiamo anche valutare di sostituire una macro-sessione del terzo giorno con una sessione più approfondita su Windows Embeddeb CE 6.0 e i relativi SDK.

Il nostro obiettivo è quello di fornire contenuti il più possibile aderenti alle vostre esigenze: per farci sapere il tuo parere scrivete direttamente a me all'indirizzo Roberto@DevLeap.it.

Ricordo a tutti che fra qualche giorno scade la possibilità di iscriversi alla confrenza a prezzo super scontato.

Posted: feb 23 2007, 03.45 by rob | with no comments
Filed under: ,
.NET Micro Frameowrk 2.0

Il 12/2 è uscito il .NET Micro Framework 2.0 SDK destinato a chi sviluppa su quanto conosciamo con il nome di SPOT. Il modello di sviluppo è classico .NET, basato su linguaggio C# (da notare che non c'è VB.NET) e integrato con Visual Studio 2005.

Non esiste un designer di interfaccia per adesso. Come sempre si fa in questi casi vi sottopongo il mio Hello World Tiny CLR di qualche anno fa in versione Micro Framework 2.0.

using System;

using Microsoft.SPOT;

using Microsoft.SPOT.Input;

using Microsoft.SPOT.Presentation;

using Microsoft.SPOT.Presentation.Controls;

namespace MFWindowApplication1
{

   public class Program : Microsoft.SPOT.Application

   {

      public static void Main()

      {

         Program myApplication = new Program();

         Window mainWindow = myApplication.CreateWindow();

         GPIOButtonInputProvider inputProvider = new GPIOButtonInputProvider(null);

         myApplication.Run(mainWindow);

      }

      private Window mainWindow;

      public Window CreateWindow()

      {

         mainWindow = new Window();

         mainWindow.Height = SystemMetrics.ScreenHeight;

         mainWindow.Width = SystemMetrics.ScreenWidth;

         Text text = new Text();

         text.Font = Resources.GetFont(Resources.FontResources.small);

         text.TextContent = Resources.GetString(Resources.StringResources.String1);

         text.HorizontalAlignment = Microsoft.SPOT.Presentation.HorizontalAlignment.Center;

         text.VerticalAlignment = Microsoft.SPOT.Presentation.VerticalAlignment.Center;

         mainWindow.Child = text;

         mainWindow.Visibility = Visibility.Visible;

         Buttons.Focus(mainWindow);

         return mainWindow;

      }

}

Posted: feb 22 2007, 11.41 by rob | with no comments
Filed under:
Windows Mobile 6.0 SDK

Il 12 Febbraio è uscito sul sito MSDN Download una preview del nuovo SDK per Windows Mobile 6, ma dopo qualche ora è stato rimosso. Sembra sia stato uno errore di pubblicazione.

Dovremmo aspettare fino al primo marzo per vederne una versione pubblica e il primo di maggio per vedere la versione completa.

La notizia arriva dal team: http://blogs.msdn.com/windowsmobile/archive/2007/02/14/where-are-the-windows-mobile-6-sdks.aspx

ASP.NET 2.0 Async Techniques

Ho pubblicato un doppio articolo sulle tecniche asincrone in ASP.NET 1.x e 2.0 pubblicato nel 2006 su Computer Programming.

Ecco il link: http://blogs.devleap.com/articolidevleap/archive/2007/02/07/asp-net-2-0-async-techniques.aspx.

Buona lettura

Posted: feb 07 2007, 10.04 by rob | with no comments
Filed under:
Windows Workflow Foundation e Thread Pool

Riprendo quanto segnalato da Paolo nel primo paragrafo del suo ottimo sul problema della rientranza delle chiamate in WF per ribadire il concetto sul numero dei thread utilizzabili in WF.

Lo scheduler di default di Windows Workflow Foundation (DefaultSchedulerService) lavora in asincrono rispetto al thread che avvia l'istanza di workflow dall'host.

Il parametro MaxSimultaneousWorkflows del DefaultSchedulerService determina quanti thread massimi simultanei sono consentiti dallo scheduler. Se il limite è impostato a 3, il DefaultWorkflowSchedulerService può lavorare con 3 thread del thread pool di .NET per eseguire i workflow. Quando viene avviata una nuova istanza di workflow, se i tre thread stanno già eseguendo altre istanze, la nuova istanza viene inserita in una coda interna al DefaultSchedulerService ed eseguita quando un thread dei 3 ritorna disponibile. Questo accodamento avviene anche dopo una sospensione o recupero del workflow tramite il PersistenceService.

I valori di default a prima vista sono molto bassi (un po' come accade per i 25 thread di ASP.NET che sembrano non pochi, ma praticamente inesistenti :-)): il numero, rappresentato da un Int32 è 5 nel caso di macchine mono-processore e calcolato con questo algoritmo nel caso di macchine multi-processore: (int)(5 * Environment.ProcessorCount * .8). A prima vista l'algoritmo restituisce gli stessi risultati di "4 * numeroprocessori", ma visto che si lavora con una regola aritmetica sugli interi non sempre restituisce lo stesso numero della semplice moltiplicazione per 4.

Alzare il numero dei thread sembra essere la soluzione per far girare più workflow in contemporanea, ma è bene ricordare che:

1) Host in ASP.NET: anche ASP.NET ha bisogno di thread del thread pool di .NET per poter servire le richieste che arrivano. Alzare quindi il numero di workflow contemporanei, se da una parte può migliorare il parallelismo fra workflow, sicuramente fa calare drasticamente il numero di thread disponibili in asp.net per servire le varie richieste all'applicazione per le varie pagine. Non tutte le pagine tra l'altro utilizzeranno workflow e quindi otteniamo un rallentamento generale dell'applicazione ingiustificato: una pagina velocissima da eseguire deve aspettare che si liberi un thread del thread pool per poter essere accolta. Inoltre è probabile che la singola richiesta per una pagina ASP.NET (una insert, un'update o una lettura di dati) sia più veloce dell'esecuzione di un flusso di operazioni di un workflow, non perchè il workflow rutime di per se sia più lento (anche se un po' di overhead lo aggiunge, ma ritengo che i benefici vadano ben oltre), ma perchè probabilmente in un workflow dobbiamo eseguire varie operazioni con una certa logica.
Questo problema non è confinato solamente a Windows Workflow Foundation: i generale tutte le operazioni complesse in ASP.NET occupano un thread del thread pool per molto tempo. Se ci mettiamo anche 10 thread, ad esempio, per lo scheduler del workflow (sui 25 totali di default) abbiamo veramente pochi thread a disposizione per le pagine.

Per una trattazione approfondita delle tematiche ASP.NET e l'esecuzione delle pagine in modo asincrono si veda l'articolo da me pubblicato su Computer Programmin nel 2006. E' diviso in due parti: Parte 1 e Parte 2.

Queste problematiche riguardano anche l'esecuzione di Workflow su un application server che condivide le richieste a più client.

2) Host fuori da ASP.NET e Application Server. Anche se non ospitiamo il workflow runtime in applicazioni server side, alzare il numero di workflow contemporanei, può non essere una buona idea.

Il motivo è lo stesso: questi thread vengono recuperati dal thread pool di .NET, lo stesso thread pool che viene utilizzato da altre operazioni nel codice. Ad esempio se usiamo un oggetto Transaction (manuale o automatico dal TransactionScope) nel codice del workflow o anche nel codice dell'host, questo signore utilizza il thread pool di .NET, di conseguenza andiamo a pestare i piedi (nel senso di cercare di utilizzare) allo stesso pool di thread utilizzato dai workflow: in pratica andiamo gestire le transazioni (che credo importanti :-)) aspettando che si liberi un thread alla fine di un workflow solo perchè vorremmo vedere tanti workflow in contemporanea. Il problema è enorme se pensate che le transazioni hanno (E DEVONO AVERE) un timeout...non è bello avere dei rollback per timeout solo perchè ci piace vedere il Concurrent Workflow ad un valore alto pensando che significhi alte prestazioni.

Come sempre un sistema deve esere guardato nel suo complesso, altrimenti toccando le singole impostazioni per migliorare una delle sue parti, si rischia di rallentare TUTTO.

Una "chicca" finale: sapete con cosa viene gestita dietro le quinte (ed è giusto che sia così) la persistenza di un workflow su DB ? Con un oggetto Transaction :-)
Quindi diventa facile andare in timeout durante la persistenza di workflow (con conseguente retry probabile che necessita sempre di un thread libero del thread pool) se aumentiamo il numero di workflow contemporanei. L'espressione tecnica per indicare questo "stallo" è: Il cane che si morde la coda.

La storia potrebbe essere questa:

Ho una applicazione ASP.NET che usa WF: spesso non riesco a eseguire quanti workflow vorrei. Alzo il numero di istanze possibili (MaxSimultaneousWorkflows a 20). Se chiamo i 20 WF da un singolo client vado come i fulmini. Penso di aver risolto il problema. Se non provo sotto carico (bastano 3/4 richieste concorrenti) non mi accorgo di niente. Poi gli utenti si lamentano della lentezza...vedo che ASP.NET ha solo 25 thread usabili e alzo il valore a 100. Penso di aver risolto...ma ho tanti thread switch che causano operazioni onerose e mi si rallenta ulteriormente il tutto...Alla fine compro un server da 200K così non ho problemi :-)...si ma per gestire un carico che potrebbe essere gestito da un server di fascia molto più bassa.

La soluzione necessita di attenzione su tutte le varie componenti: ormai i software sono molto legati l'uno all'altro e occorre fare molta attenzione nello spostare qualche flag isolato di una delle componenti. Ad esempio, se il nostro DB fa di tutto, anche le analisi comparative sul fatturato dei tre anni precedenti con query da 18 Join (magari senza indici perchè il DB lo abbiamo ereditato da sviluppatori precedenti), non possiamo pretendere che la nostra applicazioni vada veloce su quel db anche se il codice ASP.NET è performance e i thread sono pochi. Se appoggiamo i Workflow sullo stesso DB come persistenza probabilmente peggioriamo il tutto: sono tante le operazioni che il PersistenceService deve fare sul DB, soprattutto per applicazioni ASP.NET dove ogni richiesta è una toccata e fuga; il WF deve essere persistito molte volte in una singola operazioni di un utente. Magari abbiamo deciso di usare anche il TrackingService per tracciare tutto quello che ci serve...e magari lo abbiamo fatto sullo stesso DB peggiorando anche le statistiche di cui sopra.

Le soluzioni ci sono e constano nel calibrare bene i parametri. Molto spesso basta spostare un po' i carichi di lavoro, magari usando servizi di accodamento (MSMQ, Sql 2205 Broker Service, Oracle Advanced Queuing, MQSeries) rendendo il più possibile asincrono il lavoro già a partire da pagine .aspx e service .asmx, .svc, self-hosted di WCF. Su questi argomenti ci confronteremo a DevCon dove, ad oggi, in agenda abbiamo pesato ad una sessione tripla su queste tecniche. Il titolo della sessione dovrebbe essere esplicativo: Server-side Async: With some tricks your 5K Server can perform as a 40K server. Per il contenuto: http://devcon2007.devleap.com/sessioni.aspx#ALL01.

Nota conclusiva: esiste anche un ManualWorkflowSchedulerService, che lavora in sincrono risolvendo molti dei problemi accennati da Paolo nel suo post e da me in questo post. In alcuni post sul web si indica questa come soluzione. NON E' DETTO CHE SIA LA SOLUZIONE, ANZI, ma ne parliamo un'altra volta....

VS 2005 GAX GAT

 

Articolo da me pubblicato su Week.it il 21/11/2006

Visual Studio 2005 offre vari template per facilitare la creazione di progetti. Per esempio creando un progetto di tipo Window Form (Windows Application) viene creata una solution e un progetto che contiene una prima Form, un file di configurazione, un file assemblyinfo.cs, un file di risorse e, non ultime, le reference più comuni per un progetto di questo tipo.
Nel caso di creazione di una Device Application viene, invece, preparato il terreno per iniziare a creare una soluzione mobile con tanto di reference verso le librerie del .Net Compact Framework.


In pratica, con un template di progetto si ottiene un nuovo progetto con alcuni item predefiniti. Vs 2005 espone anche un menu per aggiungere item rilevanti per il progetto: per esempio, a un progetto mobile non si può aggiungere (per ora) un form Xaml, ma si può aggiungere un file .sdf.
Alcuni item fanno partire un wizard di configurazione di alcuni parametri: per continuare con l’esempio, aggiungendo un file .sdf parte il wizard di configurazione del Data Source. I template di progetto e singolo item facilitano l’uso e la creazione degli elementi del progetto. I Guidance Package estendono queste funzionalità fornendo “ricette” (recipes) preconfigurate per eseguire determinate azioni, facilitando l’uso di determinate librerie o fornendo wizard per la creazione guidata d’elementi multipli: per esempio si può creare un form con il pattern Mvp (Model View Presenter) in un passo singolo e ottendeno la classe del form, il suo presenter e la relativa configurazione. I nuovi Software Factory, disponibili su Msdn, vengono di solito accompagnati da un Guidance Package che appunto consente d’automatizzare, in modo predefinito, le operazioni più comuni del Software Factory stesso. Anche in questo caso il pacchetto contiene un Guidance Package con varie ricette per la creazione di elementi che usano il Software Factory.

Per fare in modo che Visual Studio possa utilizzare Guidance Package è necessario installare il Guidance Automation Extension. Si tratta di un componente di runtime per Visual Studio 2005 (a partire dalla versione Standard), disponibile per adesso solo in inglese, che ne estende le funzionalità.

Una volta installate le estensioni nel menu Tools di Visual Studio troviamo il Guidance Package Manager che consente di visualizzare, abilitare, disabilitare i vari Guidance Package nonchè di lanciare le singole ricette per la creazione guidata di elementi.
I Guidance Package vengono forniti in formato .msi o sorgente. Nel primo caso è sufficiente lanciare il .msi per ottenere il package nel Guidance Package Manager, nel secondo occorre installare anche il Guidance Automation Toolkit, lo strumento per creare e debuggare Package.

VSTS for DB Pro: Aggiunta e successivo Refactor di un campo

Tutte le volte si che porta in produzione una modifica di schema viene utilizzato dietro le quinte lo Schema Compare, strumento che appunto esegue una comparazione fra gli oggetti del progetto rispetto al database indicato.

Se, durante lo sviluppo, si aggiunge un campo ad una tabella e si esegue successivamente un Refactor (operazione che capita spesso quando si progettano aggiunte ad un db esistente: "aggiungo intanto il placeholder e poi decido i nomi") non si incorre nel problema di DROP table che affligge il Refactor dei campi. Questo perchè appunto lo Schema Compare vede solo le differenze fra progetto e target DB. Il risultato quindi è una ALTER TABLE per l'aggiunta del campo.

In questo caso ho aggiunto il campo DescrizioneAggiuntiva per poi eseguire un Refactor su DescrizioneAggiuntivaEx. Al termine ho creato lo script di update. 

/*

This script was created by Visual Studio on 02/02/2007 at 12.53.

Run this script on peppe.SalamiManagement.dbo to make it the same as IntroVSTSDBPRO02.

Please back up your target database before running this script.

*/

GO

SET NUMERIC_ROUNDABORT OFF

GO

SET ANSI_PADDING ON

GO

SET ANSI_WARNINGS ON

GO

SET CONCAT_NULL_YIELDS_NULL ON

GO

SET ARITHABORT ON

GO

SET QUOTED_IDENTIFIER ON

GO

SET ANSI_NULLS ON

GO

IF EXISTS (SELECT * FROM tempdb..sysobjects WHERE id=OBJECT_ID('tempdb..#tmpErrors')) DROP TABLE #tmpErrors

GO

CREATE TABLE #tmpErrors (Error int)

GO

SET XACT_ABORT ON

GO

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

GO

BEGIN TRANSACTION

GO

PRINT N'Altering [dbo].[tabSalami]'

GO

ALTER TABLE [dbo].[tabSalami] ADD

[SalameDescrizioneAggiuntivaEx] [dbo].[udtDescrizione] NULL

GO

IF @@ERROR<>0 AND @@TRANCOUNT>0 ROLLBACK TRANSACTION

GO

IF @@TRANCOUNT=0 BEGIN INSERT INTO #tmpErrors (Error) SELECT 1 BEGIN TRANSACTION END

GO

IF EXISTS (SELECT * FROM #tmpErrors) ROLLBACK TRANSACTION

GO

IF @@TRANCOUNT>0 BEGIN

PRINT 'The database update succeeded'

COMMIT TRANSACTION

END

ELSE PRINT 'The database update failed'

GO

DROP TABLE #tmpErrors

GO

Posted: feb 02 2007, 12.53 by rob | with no comments
Filed under:
[OT] Statistiche dei Post

Mi è arrivata questa domanda da uno dei nostri blogger: ho 120 aggregate view per un mio post ma sulla home dei blog vedo solo 22 View. Come mai ?

La pagina http://blogs.devleap.com riporta come View solo le visite online e non tiene conto degli Aggregate View eseguiti con RSS Reader.

Posted: feb 02 2007, 12.44 by rob | with no comments
Filed under:
VSTS for DB PRO: Schema Update per aggiunta campo

Dopo il post di ieri sul rename di un campo, ecco come si comporta VSTS for DBPro nel caso di aggiunta di un campo ad una tabella. In questi giorni, sto testando VSTS for DB Pro in vari scenari per capire come si muove dietro le quinte. 

Nel caso specifico ho aggiunto il campo DescrizioneAggiuntiva (usando un UDT esistente) alla tabella tabSalami (chi ha partecipato al VSTS Day a settembre si ricorderà questa tabella interessantissima :-)).

In questo caso viene generato una ALTER TABLE e quindi non soffriamo il DROP&RECREATE.

Il commento iniziale dice tutto: applica questo script al DB vero per renderlo identico a quanto presente nel progetto disconnesso.

/*

This script was created by Visual Studio on 02/02/2007 at 12.00.

Run this script on peppe.SalamiManagement.dbo to make it the same as IntroVSTSDBPRO02.

Please back up your target database before running this script.

*/

GO

SET NUMERIC_ROUNDABORT OFF

GO

SET ANSI_PADDING ON

GO

SET ANSI_WARNINGS ON

GO

SET CONCAT_NULL_YIELDS_NULL ON

GO

SET ARITHABORT ON

GO

SET QUOTED_IDENTIFIER ON

GO

SET ANSI_NULLS ON

GO

IF EXISTS (SELECT * FROM tempdb..sysobjects WHERE id=OBJECT_ID('tempdb..#tmpErrors')) DROP TABLE #tmpErrors

GO

CREATE TABLE #tmpErrors (Error int)

GO

SET XACT_ABORT ON

GO

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

GO

BEGIN TRANSACTION

GO

PRINT N'Altering [dbo].[tabSalami]'

GO

ALTER TABLE [dbo].[tabSalami] ADD

[SalameDescrizioneAggiuntiva] [dbo].[udtDescrizione] NULL

GO

IF @@ERROR<>0 AND @@TRANCOUNT>0 ROLLBACK TRANSACTION

GO

IF @@TRANCOUNT=0 BEGIN INSERT INTO #tmpErrors (Error) SELECT 1 BEGIN TRANSACTION END

GO

IF EXISTS (SELECT * FROM #tmpErrors) ROLLBACK TRANSACTION

GO

IF @@TRANCOUNT>0 BEGIN

PRINT 'The database update succeeded'

COMMIT TRANSACTION

END

ELSE PRINT 'The database update failed'

GO

DROP TABLE #tmpErrors

GO

Posted: feb 02 2007, 12.01 by rob | with no comments
Filed under:
VSTS for DB Pro Schema Update con Merge Replication

Una delle numerose e interessanti feature di VSTS for DB Pro consente di modificare gli oggetti database direttamente nel progetto per poi generare lo script di update che può essere applicato al DB reale o di test.

Inoltre VSTS for DB Pro consente di effettuare Refactoring consistente su oggetti DB. Ad esempio si può rinominare un campo di una tabella ottenendo in automatico il rename del campo in tutti gli oggetti db che in qualche modo hanno a che fare con il campo stesso (stored procedure, function, trigger, indici, relazioni etc).

Esiste però un problema (a cui sto cercando un workaround semplice e indolore..vi farò sapere) nello script generato per effettuare la modifica. Ad esempio: rinominando un campo si ottiene il seguente script (ho preso una tabella di un mio famoso DB di Demo).

Ho rinominato il campo Nome in CampeggioNome.

BEGIN TRANSACTION

GO

PRINT N'Dropping constraints from [dbo].[Campeggi]'

GO

ALTER TABLE [dbo].[Campeggi] DROP CONSTRAINT [PK_Campeggi]

GO

IF @@ERROR<>0 AND @@TRANCOUNT>0 ROLLBACK TRANSACTION

GO

IF @@TRANCOUNT=0 BEGIN INSERT INTO #tmpErrors (Error) SELECT 1 BEGIN TRANSACTION END

GO

PRINT N'Dropping constraints from [dbo].[Campeggi]'

GO

ALTER TABLE [dbo].[Campeggi] DROP CONSTRAINT [MSmerge_df_rowguid_F7AE60381A2441C8BA14010D6380F219]

GO

IF @@ERROR<>0 AND @@TRANCOUNT>0 ROLLBACK TRANSACTION

GO

IF @@TRANCOUNT=0 BEGIN INSERT INTO #tmpErrors (Error) SELECT 1 BEGIN TRANSACTION END

GO

DROP INDEX [MSmerge_index_661577395] ON [dbo].[Campeggi]

GO

IF @@ERROR<>0 AND @@TRANCOUNT>0 ROLLBACK TRANSACTION

GO

IF @@TRANCOUNT=0 BEGIN INSERT INTO #tmpErrors (Error) SELECT 1 BEGIN TRANSACTION END

GO

 

PRINT N'Rebuilding [dbo].[Campeggi]'

GO

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

SET XACT_ABORT ON

GO

BEGIN TRANSACTION

CREATE TABLE [dbo].[tmp_ms_xx_Campeggi]

(

[IdCampeggio] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,

[CampeggioNome] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,

[rowguid] [uniqueidentifier] NOT NULL ROWGUIDCOL CONSTRAINT [MSmerge_df_rowguid_F7AE60381A2441C8BA14010D6380F219] DEFAULT (newsequentialid())

) ON [PRIMARY]

INSERT INTO [dbo].[tmp_ms_xx_Campeggi]([IdCampeggio], [rowguid]) SELECT [IdCampeggio], [rowguid] FROM [dbo].[Campeggi]

DROP TABLE [dbo].[Campeggi]

EXEC sp_rename N'[dbo].[tmp_ms_xx_Campeggi]', N'Campeggi'

COMMIT TRANSACTION

GO

IF @@ERROR<>0 AND @@TRANCOUNT>0 ROLLBACK TRANSACTION

GO

IF @@TRANCOUNT=0 BEGIN INSERT INTO #tmpErrors (Error) SELECT 1 BEGIN TRANSACTION END

GO

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

GO

PRINT N'Creating primary key [PK_Campeggi] on [dbo].[Campeggi]'

GO

ALTER TABLE [dbo].[Campeggi] ADD CONSTRAINT [PK_Campeggi] PRIMARY KEY CLUSTERED ([IdCampeggio]) ON [PRIMARY]

GO

IF @@ERROR<>0 AND @@TRANCOUNT>0 ROLLBACK TRANSACTION

GO

IF @@TRANCOUNT=0 BEGIN INSERT INTO #tmpErrors (Error) SELECT 1 BEGIN TRANSACTION END

GO

PRINT N'Creating index [MSmerge_index_661577395] on [dbo].[Campeggi]'

GO

CREATE UNIQUE NONCLUSTERED INDEX [MSmerge_index_661577395] ON [dbo].[Campeggi] ([rowguid]) ON [PRIMARY]

GO

IF @@ERROR<>0 AND @@TRANCOUNT>0 ROLLBACK TRANSACTION

GO

IF @@TRANCOUNT=0 BEGIN INSERT INTO #tmpErrors (Error) SELECT 1 BEGIN TRANSACTION END

GO

 

Come si nota vengono dapprima rimossi indici, constraint e trigger per poi

1) Creare una tabella temporanea con la nuova struttura

2) Importare i dati dalla tabella originale nella tabella temporanea

3) Eseguire un DROP della tabella originale

4) Rinominare la tabella temporanea con il nome originale

Questa operazione, è impossibile da eseguire se la tabella è stata oggetto di una pubblicazione. Quando una tabella è stata inserita in una Publication di una replica di tipo merge non può essere rimossa dal DB se non dopo aver tolto il riferimento nella pubblicazione.

Quindi l'aggiornamento automatico da DB Professional non può essere effettuato e occorre modificare lo script generato per tutte le tabelle sotto Merge Replication. In pratica lo stesso risultato che si ottiene da Management Studio o dall'Enterprise Manager.

 

Posted: feb 01 2007, 12.22 by rob | with no comments |
Filed under: