Implementieren eines Geschäftslogikhandlers für einen MergeartikelImplement a Business Logic Handler for a Merge Article

Gilt für: JaSQL Server NeinAzure SQL-Datenbank NeinAzure Synapse Analytics (SQL DW) NeinParallel Data Warehouse APPLIES TO: yesSQL Server noAzure SQL Database noAzure Synapse Analytics (SQL DW) noParallel Data Warehouse

In diesem Thema wird beschrieben, wie ein Geschäftslogikhandler für einen Mergeartikel mit Replikationsprogrammierung oder Replikationsverwaltungsobjekten (RMO) in SQL ServerSQL Server implementiert wird.This topic describes how to implement a business logic handler for a merge article in SQL ServerSQL Server by using replication programming or Replication Management Objects (RMO).

Der Microsoft.SqlServer.Replication.BusinessLogicSupport -Namespace implementiert eine Schnittstelle, mit der Sie eine komplexe Geschäftslogik zum Verarbeiten von Ereignissen schreiben können, die während der Synchronisierung der Mergereplikation eintreten.The Microsoft.SqlServer.Replication.BusinessLogicSupport namespace implements an interface that enables you to write complex business logic to handle events that occur during the merge replication synchronization process. Die Methoden im Geschäftslogikhandler können vom Replikationsvorgang für jede geänderte Zeile aufgerufen werden, die während der Synchronisierung repliziert wird.Methods in the business logic handler can be invoked by the replication process for each changed row that is replicated during synchronization.

Der allgemeine Vorgang zum Implementieren eines Geschäftslogikhandlers ist Folgender:The general process for implementing a business logic handler is:

  1. Erstellen Sie die Geschäftslogikhandler-Assembly.Create the business logic hander assembly.

  2. Registrieren Sie die Assembly beim Verteiler.Register the assembly at the Distributor.

  3. Stellen Sie die Assembly auf dem Server bereit, auf dem der Merge-Agent ausgeführt wird.Deploy the assembly at the server on which the Merge Agent runs. Für ein Pullabonnement wird der Agent auf dem Abonnenten ausgeführt, und für ein Pushabonnement wird der Agent auf dem Verteiler ausgeführt.For a pull subscription the agent runs on the Subscriber, and for a push subscription the agent runs on the Distributor. Wenn Sie die Websynchronisierung verwenden, wird der Agent auf dem Webserver ausgeführt.When you are using Web synchronization, the agent runs on the Web server.

  4. Erstellen Sie einen Artikel, der den Geschäftslogikhandler verwendet, oder ändern Sie einen vorhandenen Artikel so, dass er den Geschäftslogikhandler verwendet.Create an article that uses the business logic handler or modify an existing article to use the business logic handler.

Der von Ihnen angegebene Geschäftslogikhandler wird für jede Zeile ausgeführt, die synchronisiert wird.The business logic handler you specify is executed for every row that is synchronized. Eine komplexe Logik und Aufrufe anderer Anwendungen oder Netzwerkdienste können sich auf die Leistung auswirken.Complex logic and calls to other applications or network services can impact performance. Weitere Informationen zu Geschäftslogikhandlern finden Sie unter Ausführen der Geschäftslogik während der Mergesynchronisierung.For more information about business logic handlers, see Execute Business Logic During Merge Synchronization.

In diesem ThemaIn This Topic

Verwenden der ReplikationsprogrammierungUsing Replication Programming

So erstellen Sie einen Geschäftslogikhandler und stellen ihn bereitTo create and deploy a business logic handler

  1. Erstellen Sie in MicrosoftMicrosoft Visual Studio ein neues Projekt für die .NET-Assembly mit dem Code, der den Geschäftslogikhandler implementiert.In MicrosoftMicrosoft Visual Studio, create a new project for the .NET assembly that contains the code that implements the business logic handler.

  2. Fügen Sie Verweise auf das Projekt für die folgenden Namespaces hinzu.Add references to the project for the following namespaces.

    AssemblyverweisAssembly Reference SpeicherortLocation
    Microsoft.SqlServer.Replication.BusinessLogicSupport C:\Programme\Microsoft SQL Server\nnnC:\Program Files\Microsoft SQL Server\nnn\COM (Standardinstallation)COM (default installation)
    System.Data GAC (Komponente von .NET Framework)GAC (component of the .NET Framework)
    System.Data.Common GAC (Komponente von .NET Framework)GAC (component of the .NET Framework)
  3. Fügen Sie eine Klasse hinzu, die die BusinessLogicModule -Klasse überschreibt.Add a class that overrides the BusinessLogicModule class.

  4. Implementieren Sie die HandledChangeStates -Eigenschaft, um die Typen von Änderungen anzugeben, die verarbeitet werden.Implement the HandledChangeStates property to indicate the types of changes that are handled.

  5. Überschreiben Sie mindestens eine der folgenden Methoden der BusinessLogicModule -Klasse:Override one or more of the following methods of the BusinessLogicModule class:

    • CommitHandler – wird aufgerufen, wenn während der Synchronisierung ein Commit für eine Datenänderung ausgeführt wird.CommitHandler - invoked when a data change is committed during synchronization.

    • DeleteErrorHandler – wird aufgerufen, wenn beim Hochladen oder Herunterladen einer DELETE-Anweisung ein Fehler auftritt.DeleteErrorHandler - invoked when an error occurs when a DELETE statement is being uploaded or downloaded.

    • DeleteHandler – wird aufgerufen, wenn DELETE-Anweisungen hochgeladen oder heruntergeladen werden.DeleteHandler - invoked when DELETE statements are being uploaded or downloaded.

    • InsertErrorHandler – wird aufgerufen, wenn beim Hochladen oder Herunterladen einer INSERT-Anweisung ein Fehler auftritt.InsertErrorHandler - invoked when an error occurs when an INSERT statement is being uploaded or downloaded.

    • InsertHandler – wird aufgerufen, wenn INSERT-Anweisungen hochgeladen oder heruntergeladen werden.InsertHandler - invoked when INSERT statements are being uploaded or downloaded.

    • UpdateConflictsHandler – wird aufgerufen, wenn in Konflikt stehende UPDATE-Anweisungen auf dem Verleger und dem Abonnenten auftreten.UpdateConflictsHandler - invoked when conflicting UPDATE statements occur at the Publisher and Subscriber.

    • UpdateDeleteConflictHandler – wird aufgerufen, wenn UPDATE-Anweisungen mit DELETE-Anweisungen auf dem Verleger und dem Abonnenten in Konflikt stehen.UpdateDeleteConflictHandler - invoked when UPDATE statements conflict with DELETE statements at the Publisher and Subscriber.

    • UpdateErrorHandler – wird aufgerufen, wenn beim Hochladen oder Herunterladen einer UPDATE-Anweisung ein Fehler auftritt.UpdateErrorHandler - invoked when an error occurs when an UPDATE statement is being uploaded or downloaded.

    • UpdateHandler – wird aufgerufen, wenn UPDATE-Anweisungen hochgeladen oder heruntergeladen werden.UpdateHandler - invoked when UPDATE statements are being uploaded or downloaded.

  6. Erstellen Sie das Projekt, um die Geschäftslogikhandler-Assembly zu erstellen.Build the project to create the business logic handler assembly.

  7. Stellen Sie die Assembly in dem Verzeichnis mit der ausführbaren Datei für den Merge-Agent (replmerg.exe) bereit (bei der Standardinstallation ist dies C:\Programme\Microsoft SQL Server\nnnC:\Program Files\Microsoft SQL Server\nnn\COM), oder installieren Sie sie im globalen Assemblycache (GAC) von .NET.Deploy the assembly in the directory that contains the Merge Agent executable file (replmerg.exe), which for a default installation is C:\Programme\Microsoft SQL Server\nnnC:\Program Files\Microsoft SQL Server\nnn\COM, or install it in the .NET global assembly cache (GAC). Installieren Sie die Assembly nur dann im GAC, wenn andere Anwendungen als der Merge-Agent auf die Assembly zugreifen müssen.You should only install the assembly in the GAC if applications other than the Merge Agent require access to the assembly. Die Assembly kann mit dem im .NET Framework SDK bereitgestellten Global Assembly Cache-Tool (Gacutil.exe ) im GAC installiert werden.The assembly can be installed into the GAC using the Global Assembly Cache tool (Gacutil.exe) provided in the .NET Framework SDK.

    Hinweis

    Auf jedem Server, auf dem der Merge-Agent ausgeführt wird, muss ein Geschäftslogikhandler bereitgestellt werden. Dazu gehört auch der IIS-Server, der die Datei replisapi.dll hostet, wenn die Websynchronisierung verwendet wird.A business logic handler must be deployed on every server on which the Merge Agent runs, which includes the IIS server that hosts the replisapi.dll when using Web synchronization.

So registrieren Sie einen GeschäftslogikhandlerTo register a business logic handler

  1. Führen Sie auf dem Verleger sp_enumcustomresolvers (Transact-SQL) aus, um zu prüfen, ob die Assembly noch nicht als Geschäftslogikhandler registriert wurde.At the Publisher, execute sp_enumcustomresolvers (Transact-SQL) to verify that the assembly has not already been registered as a business logic handler.

  2. Führen Sie auf dem Verteiler sp_registercustomresolver (Transact-SQL) aus. Geben Sie dabei für @article_resolver einen Anzeigenamen für den Geschäftslogikhandler, für @is_dotnet_assembly den Wert true, für @dotnet_assembly_name den Namen der Assembly und für @dotnet_class_name den vollqualifizierten Namen der Klasse, die BusinessLogicModule überschreibt, an.At the Distributor, execute sp_registercustomresolver (Transact-SQL), specifying a friendly name for the business logic handler for @article_resolver, a value of true for @is_dotnet_assembly, the name of the assembly for @dotnet_assembly_name, and the fully-qualified name of the class that overrides BusinessLogicModule for @dotnet_class_name.

    Hinweis

    Sie müssen den vollständigen Pfad mit dem Assemblynamen für @dotnet_assembly_name angeben, falls die Assembly nicht im gleichen Verzeichnis wie die ausführbare Datei für den Merge-Agent, im gleichen Verzeichnis wie die Anwendung, mit der der Merge-Agent synchron gestartet wird, oder im globalen Assemblycache (GAC) bereitgestellt wird.If the assembly is not deployed in the same directory as the Merge Agent executable, in the same directory as the application that synchronously starts the Merge Agent, or in the global assembly cache (GAC), you need to specify the full path with the assembly name for @dotnet_assembly_name. Wenn Sie die Websynchronisierung verwenden, müssen Sie den Speicherort der Assembly auf dem Webserver angeben.When using Web synchronization, you must specify the location of assembly at the Web server.

So verwenden Sie einen Geschäftslogikhandler mit einem neuen TabellenartikelTo use a business logic handler with a new table article

  1. Führen Sie sp_addmergearticle (Transact-SQL) aus, um einen Artikel zu definieren. Geben Sie dabei für article_resolver@ den Anzeigenamen des Geschäftslogikhandlers an.Execute sp_addmergearticle (Transact-SQL) to define an article, specifying the friendly name of the business logic handler for @article_resolver. Weitere Informationen finden Sie unter Definieren eines Artikels.For more information, see Define an Article.

So verwenden Sie einen Geschäftslogikhandler mit einem bestehenden TabellenartikelTo use a business logic handler with an existing table article

  1. Führen Sie sp_changemergearticle (Transact-SQL) aus. Geben Sie dabei @publication, @article, den Wert article_resolver für @property und den Anzeigenamen des Geschäftslogikhandlers für @value an.Execute sp_changemergearticle (Transact-SQL), specifying @publication, @article, a value of article_resolver for @property, and the friendly name of the business logic handler for @value.

Beispiele (Replikationsprogrammierung)Examples (Replication Programming)

In diesem Beispiel wird ein Geschäftslogikhandler gezeigt, der ein Überwachungsprotokoll erstellt.This example shows a business logic handler that creates an audit log.

using System;
using System.Text;
using System.Data;
using System.Data.Common;
using Microsoft.SqlServer.Replication.BusinessLogicSupport;
using Microsoft.Samples.SqlServer.BusinessLogicHandler;

namespace Microsoft.Samples.SqlServer.BusinessLogicHandler
{
    public class OrderEntryBusinessLogicHandler :
      Microsoft.SqlServer.Replication.BusinessLogicSupport.BusinessLogicModule
    {
        // Variables to hold server names.
        private string publisherName;
        private string subscriberName;

        public OrderEntryBusinessLogicHandler()
        {
        }

        // Implement the Initialize method to get publication 
        // and subscription information.
        public override void Initialize(
            string publisher,
            string subscriber,
            string distributor,
            string publisherDB,
            string subscriberDB,
            string articleName)
        {
            // Set the Publisher and Subscriber names.
            publisherName = publisher;
            subscriberName = subscriber;
        }

        // Declare what types of row changes, conflicts, or errors to handle.
        override public ChangeStates HandledChangeStates
        {
            get
            {
                // Handle Subscriber inserts, updates and deletes.
                return ChangeStates.SubscriberInserts |
                  ChangeStates.SubscriberUpdates | ChangeStates.SubscriberDeletes;
            }
        }

        public override ActionOnDataChange InsertHandler(SourceIdentifier insertSource,
          DataSet insertedDataSet, ref DataSet customDataSet, ref int historyLogLevel,
          ref string historyLogMessage)
        {
            if (insertSource == SourceIdentifier.SourceIsSubscriber)
            {
                // Build a line item in the audit message to log the Subscriber insert.
                StringBuilder AuditMessage = new StringBuilder();
                AuditMessage.Append(String.Format("A new order was entered at {0}. " +
                  "The SalesOrderID for the order is :", subscriberName));
                AuditMessage.Append(insertedDataSet.Tables[0].Rows[0]["SalesOrderID"].ToString());
                AuditMessage.Append("The order must be shipped by :");
                AuditMessage.Append(insertedDataSet.Tables[0].Rows[0]["DueDate"].ToString());

                // Set the reference parameter to write the line to the log file.
                historyLogMessage = AuditMessage.ToString();
                
                // Set the history log level to the default verbose level.
                historyLogLevel = 1;

                // Accept the inserted data in the Subscriber's data set and 
                // apply it to the Publisher.
                return ActionOnDataChange.AcceptData;
            }
            else
            {
                return base.InsertHandler(insertSource, insertedDataSet, ref customDataSet,
                  ref historyLogLevel, ref historyLogMessage);
            }
        }

        public override ActionOnDataChange UpdateHandler(SourceIdentifier updateSource,
          DataSet updatedDataSet, ref DataSet customDataSet, ref int historyLogLevel,
          ref string historyLogMessage)
        {
            if (updateSource == SourceIdentifier.SourceIsPublisher)
            {
                // Build a line item in the audit message to log the Subscriber update.
                StringBuilder AuditMessage = new StringBuilder();
                AuditMessage.Append(String.Format("An existing order was updated at {0}. " +
                  "The SalesOrderID for the order is ", subscriberName));
                AuditMessage.Append(updatedDataSet.Tables[0].Rows[0]["SalesOrderID"].ToString());
                AuditMessage.Append("The order must now be shipped by :");
                AuditMessage.Append(updatedDataSet.Tables[0].Rows[0]["DueDate"].ToString());

                // Set the reference parameter to write the line to the log file.
                historyLogMessage = AuditMessage.ToString();
                // Set the history log level to the default verbose level.
                historyLogLevel = 1;

                // Accept the updated data in the Subscriber's data set and apply it to the Publisher.
                return ActionOnDataChange.AcceptData;
            }
            else
            {
                return base.UpdateHandler(updateSource, updatedDataSet,
                  ref customDataSet, ref historyLogLevel, ref historyLogMessage);
            }
        }

        public override ActionOnDataDelete DeleteHandler(SourceIdentifier deleteSource,
          DataSet deletedDataSet, ref int historyLogLevel, ref string historyLogMessage)
        {
            if (deleteSource == SourceIdentifier.SourceIsSubscriber)
            {
                // Build a line item in the audit message to log the Subscriber deletes.
                // Note that the rowguid is the only information that is 
                // available in the dataset.
                StringBuilder AuditMessage = new StringBuilder();
                AuditMessage.Append(String.Format("An existing order was deleted at {0}. " +
                  "The rowguid for the order is ", subscriberName));
                AuditMessage.Append(deletedDataSet.Tables[0].Rows[0]["rowguid"].ToString());

                // Set the reference parameter to write the line to the log file.
                historyLogMessage = AuditMessage.ToString();
                // Set the history log level to the default verbose level.
                historyLogLevel = 1;

                // Accept the delete and apply it to the Publisher.
                return ActionOnDataDelete.AcceptDelete;
            }
            else
            {
                return base.DeleteHandler(deleteSource, deletedDataSet,
                  ref historyLogLevel, ref historyLogMessage);
            }
        }
    }
}
Imports System
Imports System.Text
Imports System.Data
Imports System.Data.Common
Imports Microsoft.SqlServer.Replication.BusinessLogicSupport

Namespace Microsoft.Samples.SqlServer.BusinessLogicHandler
    Public Class OrderEntryBusinessLogicHandler
        Inherits BusinessLogicModule

        ' Variables to hold server names.
        Private publisherName As String
        Private subscriberName As String

        ' Implement the Initialize method to get publication 
        ' and subscription information.
        Public Overrides Sub Initialize( _
        ByVal publisher As String, _
        ByVal subscriber As String, _
        ByVal distributor As String, _
        ByVal publisherDB As String, _
        ByVal subscriberDB As String, _
        ByVal articleName As String _
      )
            ' Set the Publisher and Subscriber names.
            publisherName = publisher
            subscriberName = subscriber
        End Sub

        ' Declare what types of row changes, conflicts, or errors to handle.
        Public Overrides ReadOnly Property HandledChangeStates() As ChangeStates
            Get
                ' Handle Subscriber inserts, updates and deletes.
                Return (ChangeStates.SubscriberInserts Or _
                 ChangeStates.SubscriberUpdates Or ChangeStates.SubscriberDeletes)
            End Get
        End Property

        Public Overrides Function InsertHandler(ByVal insertSource As SourceIdentifier, _
        ByVal insertedDataSet As DataSet, ByRef customDataSet As DataSet, _
        ByRef historyLogLevel As Integer, ByRef historyLogMessage As String) _
        As ActionOnDataChange

            If insertSource = SourceIdentifier.SourceIsSubscriber Then
                ' Build a line item in the audit message to log the Subscriber insert.
                Dim AuditMessage As StringBuilder = New StringBuilder()
                AuditMessage.Append(String.Format("A new order was entered at {0}. " + _
                 "The SalesOrderID for the order is :", subscriberName))
                AuditMessage.Append(insertedDataSet.Tables(0).Rows(0)("SalesOrderID").ToString())
                AuditMessage.Append("The order must be shipped by :")
                AuditMessage.Append(insertedDataSet.Tables(0).Rows(0)("DueDate").ToString())

                ' Set the reference parameter to write the line to the log file.
                historyLogMessage = AuditMessage.ToString()

                ' Set the history log level to the default verbose level.
                historyLogLevel = 1

                ' Accept the inserted data in the Subscriber's data set and 
                ' apply it to the Publisher.
                Return ActionOnDataChange.AcceptData
            Else
                Return MyBase.InsertHandler(insertSource, insertedDataSet, customDataSet, _
                 historyLogLevel, historyLogMessage)
            End If
        End Function
        Public Overrides Function UpdateHandler(ByVal updateSource As SourceIdentifier, _
        ByVal updatedDataSet As DataSet, ByRef customDataSet As DataSet, _
        ByRef historyLogLevel As Integer, ByRef historyLogMessage As String) _
        As ActionOnDataChange

            If updateSource = SourceIdentifier.SourceIsPublisher Then
                ' Build a line item in the audit message to log the Subscriber update.
                Dim AuditMessage As StringBuilder = New StringBuilder()
                AuditMessage.Append(String.Format("An existing order was updated at {0}. " + _
                 "The SalesOrderID for the order is ", subscriberName))
                AuditMessage.Append(updatedDataSet.Tables(0).Rows(0)("SalesOrderID").ToString())
                AuditMessage.Append("The order must now be shipped by :")
                AuditMessage.Append(updatedDataSet.Tables(0).Rows(0)("DueDate").ToString())

                ' Set the reference parameter to write the line to the log file.
                historyLogMessage = AuditMessage.ToString()
                ' Set the history log level to the default verbose level.
                historyLogLevel = 1

                ' Accept the updated data in the Subscriber's data set and apply it to the Publisher.
                Return ActionOnDataChange.AcceptData
            Else
                Return MyBase.UpdateHandler(updateSource, updatedDataSet, _
                 customDataSet, historyLogLevel, historyLogMessage)
            End If
        End Function
        Public Overrides Function DeleteHandler(ByVal deleteSource As SourceIdentifier, _
        ByVal deletedDataSet As DataSet, ByRef historyLogLevel As Integer, _
         ByRef historyLogMessage As String) As ActionOnDataDelete
            If deleteSource = SourceIdentifier.SourceIsSubscriber Then
                ' Build a line item in the audit message to log the Subscriber deletes.
                ' Note that the rowguid is the only information that is 
                ' available in the dataset.
                Dim AuditMessage As StringBuilder = New StringBuilder()
                AuditMessage.Append(String.Format("An existing order was deleted at {0}. " + _
                 "The rowguid for the order is ", subscriberName))
                AuditMessage.Append(deletedDataSet.Tables(0).Rows(0)("rowguid").ToString())

                ' Set the reference parameter to write the line to the log file.
                historyLogMessage = AuditMessage.ToString()
                ' Set the history log level to the default verbose level.
                historyLogLevel = 1

                ' Accept the delete and apply it to the Publisher.
                Return ActionOnDataDelete.AcceptDelete
            Else
                Return MyBase.DeleteHandler(deleteSource, deletedDataSet, _
                 historyLogLevel, historyLogMessage)
            End If
        End Function
    End Class
End Namespace

Das folgende Beispiel registriert eine Geschäftslogikhandler-Assembly auf dem Verteiler und ändert einen bestehenden Mergeartikel so, dass diese benutzerdefinierte Geschäftslogik verwendet wird.The following example registers a business logic handler assembly at the Distributor and changes an existing merge article to use this custom business logic.

DECLARE @publication AS sysname;
DECLARE @article AS sysname;
DECLARE @friendlyname AS sysname;
DECLARE @assembly AS nvarchar(500);
DECLARE @class AS sysname;
SET @publication = N'AdvWorksCustomers';
SET @article = N'Customers';
SET @friendlyname = N'OrderEntryLogic';
SET @assembly = N'C:\Program Files\Microsoft SQL Server\120\COM\CustomLogic.dll';
SET @class = N'Microsoft.Samples.SqlServer.BusinessLogicHandler.OrderEntryBusinessLogicHandler';

-- Register the business logic handler at the Distributor.
EXEC sys.sp_registercustomresolver 
    @article_resolver = @friendlyname,
    @resolver_clsid = NULL,
    @is_dotnet_assembly = N'true',
    @dotnet_assembly_name = @assembly,
    @dotnet_class_name = @class;

-- Add an article that uses the business logic handler
-- at the Publisher.
EXEC sp_changemergearticle 
    @publication = @publication, 
    @article = @article,
    @property = N'article_resolver', 
    @value = @friendlyname,
    @force_invalidate_snapshot = 0,
    @force_reinit_subscription = 0;
GO

Verwenden von Replikationsverwaltungsobjekten (RMO)Using Replication Management Objects (RMO)

So erstellen Sie einen GeschäftslogikhandlerTo create a business logic handler

  1. Erstellen Sie in MicrosoftMicrosoft Visual Studio ein neues Projekt für die .NET-Assembly mit dem Code, der den Geschäftslogikhandler implementiert.In MicrosoftMicrosoft Visual Studio, create a new project for the .NET assembly that contains the code that implements the business logic handler.

  2. Fügen Sie Verweise auf das Projekt für die folgenden Namespaces hinzu.Add references to the project for the following namespaces.

    AssemblyverweisAssembly Reference SpeicherortLocation
    Microsoft.SqlServer.Replication.BusinessLogicSupport C:\Programme\Microsoft SQL Server\nnnC:\Program Files\Microsoft SQL Server\nnn\COM (Standardinstallation)COM (default installation)
    System.Data GAC (Komponente von .NET Framework)GAC (component of the .NET Framework)
    System.Data.Common GAC (Komponente von .NET Framework)GAC (component of the .NET Framework)
  3. Fügen Sie eine Klasse hinzu, die die BusinessLogicModule -Klasse überschreibt.Add a class that overrides the BusinessLogicModule class.

  4. Implementieren Sie die HandledChangeStates -Eigenschaft, um die Typen von Änderungen anzugeben, die verarbeitet werden.Implement the HandledChangeStates property to indicate the types of changes that are handled.

  5. Überschreiben Sie mindestens eine der folgenden Methoden der BusinessLogicModule -Klasse:Override one or more of the following methods of the BusinessLogicModule class:

    • CommitHandler – wird aufgerufen, wenn während der Synchronisierung ein Commit für eine Datenänderung ausgeführt wird.CommitHandler - invoked when a data change is committed during synchronization.

    • DeleteErrorHandler – wird aufgerufen, wenn ein Fehler auftritt, während eine DELETE-Anweisung hochgeladen oder heruntergeladen wird.DeleteErrorHandler - invoked if an error occurs while a DELETE statement is being uploaded or downloaded.

    • DeleteHandler – wird aufgerufen, wenn DELETE-Anweisungen hochgeladen oder heruntergeladen werden.DeleteHandler - invoked when DELETE statements are being uploaded or downloaded.

    • InsertErrorHandler – wird aufgerufen, wenn ein Fehler auftritt, während eine INSERT-Anweisung hochgeladen oder heruntergeladen wird.InsertErrorHandler - invoked if an error occurs when an INSERT statement is being uploaded or downloaded.

    • InsertHandler – wird aufgerufen, wenn INSERT-Anweisungen hochgeladen oder heruntergeladen werden.InsertHandler - invoked when INSERT statements are being uploaded or downloaded.

    • UpdateConflictsHandler – wird aufgerufen, wenn in Konflikt stehende UPDATE-Anweisungen auf dem Verleger und dem Abonnenten auftreten.UpdateConflictsHandler - invoked when conflicting UPDATE statements occur at the Publisher and Subscriber.

    • UpdateDeleteConflictHandler – wird aufgerufen, wenn UPDATE-Anweisungen mit DELETE-Anweisungen auf dem Verleger und dem Abonnenten in Konflikt stehen.UpdateDeleteConflictHandler - invoked when UPDATE statements conflict with DELETE statements at the Publisher and Subscriber.

    • UpdateErrorHandler – wird aufgerufen, wenn ein Fehler auftritt, während eine UPDATE-Anweisung hochgeladen oder heruntergeladen wird.UpdateErrorHandler - invoked if an error occurs when an UPDATE statement is being uploaded or downloaded.

    • UpdateHandler – wird aufgerufen, wenn UPDATE-Anweisungen hochgeladen oder heruntergeladen werden.UpdateHandler - invoked when UPDATE statements are being uploaded or downloaded.

    Hinweis

    Alle Artikelkonflikte, die nicht explizit von Ihrem benutzerdefinierten Geschäftslogikhandler verarbeitet werden, werden vom Standardkonfliktlöser für den Artikel bearbeitet.Any article conflicts not explicitly handled by your custom business logic are handled by the default resolver for the article.

  6. Erstellen Sie das Projekt, um die Geschäftslogikhandler-Assembly zu erstellen.Build the project to create the business logic handler assembly.

So registrieren Sie einen GeschäftslogikhandlerTo register a business logic handler

  1. Erstellen Sie eine Verbindung mit dem Verteiler, indem Sie die ServerConnection -Klasse verwenden.Create a connection to the Distributor by using the ServerConnection class.

  2. Erstellen Sie eine Instanz der ReplicationServer -Klasse.Create an instance of the ReplicationServer class. Übergeben Sie ServerConnection von Schritt 1.Pass the ServerConnection from step 1.

  3. Rufen Sie EnumBusinessLogicHandlers auf, und überprüfen Sie das zurückgegebene ArrayList -Objekt, um sicherzustellen, dass die Assembly noch nicht als Geschäftslogikhandler registriert wurde.Call EnumBusinessLogicHandlers and check the returned ArrayList object to ensure that the assembly has not already been registered as a business logic handler.

  4. Erstellen Sie eine Instanz der BusinessLogicHandler -Klasse.Create an instance of the BusinessLogicHandler class. Geben Sie die folgenden Eigenschaften an:Specify the following properties:

    • DotNetAssemblyName – der Name der .NET-Assembly.DotNetAssemblyName - the name of the .NET assembly. Sie müssen den vollständigen Pfad mit dem Assemblynamen angeben, falls die Assembly nicht im gleichen Verzeichnis wie die ausführbare Datei für den Merge-Agent, im gleichen Verzeichnis wie die Anwendung, mit der der Merge-Agent synchron gestartet wird, oder im GAC bereitgestellt wird.If the assembly is not deployed in the same directory as the Merge Agent executable, in the same directory as the application that synchronously starts the Merge Agent, or in the GAC, you must include the full path with the assembly name. Sie müssen den vollständigen Pfad mit dem Assemblynamen angeben, wenn Sie einen Geschäftslogikhandler mit der Websynchronisierung verwenden.You must include the full path with the assembly name when using a business logic handler with Web synchronization.

    • DotNetClassName – der vollqualifizierte Name der Klasse, die BusinessLogicModule überschreibt und den Geschäftslogikhandler implementiert.DotNetClassName - the fully-qualified name of the class that overrides BusinessLogicModule and implements the business logic handler.

    • FriendlyName – ein Anzeigename, den Sie beim Zugriff auf den Geschäftslogikhandler verwenden.FriendlyName - a friendly name you use when you access the business logic handler.

    • IsDotNetAssembly – der Wert true.IsDotNetAssembly - a value of true.

So stellen Sie einen Geschäftslogikhandler bereitTo deploy a business logic handler

  1. Stellen Sie die Assembly auf dem Server, auf dem der Merge-Agent ausgeführt wird, in dem Dateispeicherort bereit, der angegeben wurde, als der Geschäftslogikhandler beim Verteiler registriert wurde.Deploy the assembly on the server where the Merge Agent runs in the file location specified when the business logic handler was registered at the Distributor. Für ein Pullabonnement wird der Agent auf dem Abonnenten ausgeführt, und für ein Pushabonnement wird der Agent auf dem Verteiler ausgeführt.For a pull subscription the agent runs on the Subscriber, and for a push subscription the agent runs on the Distributor. Wenn Sie die Websynchronisierung verwenden, wird der Agent auf dem Webserver ausgeführt.When you are using Web synchronization, the agent runs on the Web server. Wenn der vollständige Pfad beim Registrieren des Geschäftslogikhandlers nicht zusammen mit dem Assemblynamen angegeben wurde, stellen Sie die Assembly im gleichen Verzeichnis wie die ausführbare Datei für den Merge-Agent, im gleichen Verzeichnis wie die Anwendung, mit der der Merge-Agent synchron gestartet wird, bereit.If the full path was not included with the assembly name when the business logic handler was registered, deploy the assembly in the same directory as the Merge Agent executable, in the same directory as the application that synchronously starts the Merge Agent. Sie können die Assembly im GAC installieren, wenn es mehrere Anwendungen gibt, die die gleiche Assembly verwenden.You may install the assembly in the GAC if there are multiple applications that use the same assembly.

So verwenden Sie einen Geschäftslogikhandler mit einem neuen TabellenartikelTo use a business logic handler with a new table article

  1. Erstellen Sie eine Verbindung mit dem Verleger, indem Sie die ServerConnection -Klasse verwenden.Create a connection to the Publisher by using the ServerConnection class.

  2. Erstellen Sie eine Instanz der MergeArticle -Klasse.Create an instance of the MergeArticle class. Legen Sie die folgenden Eigenschaften fest:Set the following properties:

  3. Rufen Sie die Create -Methode auf.Call the Create method. Weitere Informationen finden Sie unter Definieren eines Artikels.For more information, see Define an Article.

So verwenden Sie einen Geschäftslogikhandler mit einem bestehenden TabellenartikelTo use a business logic handler with an existing table article

  1. Erstellen Sie eine Verbindung mit dem Verleger, indem Sie die ServerConnection -Klasse verwenden.Create a connection to the Publisher by using the ServerConnection class.

  2. Erstellen Sie eine Instanz der MergeArticle -Klasse.Create an instance of the MergeArticle class.

  3. Legen Sie die Eigenschaften Name, PublicationNameund DatabaseName fest.Set the Name, PublicationName, and DatabaseName properties.

  4. Legen Sie die Verbindung aus Schritt 1 für die ConnectionContext -Eigenschaft fest.Set the connection from step 1 for the ConnectionContext property.

  5. Rufen Sie die LoadProperties -Methode auf, um die Eigenschaften des Objekts abzurufen.Call the LoadProperties method to get the properties of the object. Wenn diese Methode falsezurückgibt, wurden entweder die Artikeleigenschaften in Schritt 3 falsch definiert, oder der Artikel ist nicht vorhanden.If this method returns false, either the article properties in step 3 were defined incorrectly or the article does not exist. Weitere Informationen finden Sie unter View and Modify Article Properties.For more information, see View and Modify Article Properties.

  6. Legen Sie den Anzeigenamen des Geschäftslogikhandlers für ArticleResolverfest.Set the friendly name of the business logic handler for ArticleResolver. Dies ist der Wert der FriendlyName -Eigenschaft, die beim Registrieren des Geschäftslogikhandlers angegeben wird.This is the value of the FriendlyName property specified when registering the business logic handler.

Beispiele (RMO)Examples (RMO)

Dieses Beispiel zeigt einen Geschäftslogikhandler, der Informationen über Einfüge-, Update- und Löschvorgänge auf dem Abonnenten protokolliert.This example is a business logic handler that logs information about inserts, updates, and deletes at the Subscriber.

using System;
using System.Text;
using System.Data;
using System.Data.Common;
using Microsoft.SqlServer.Replication.BusinessLogicSupport;
using Microsoft.Samples.SqlServer.BusinessLogicHandler;

namespace Microsoft.Samples.SqlServer.BusinessLogicHandler
{
    public class OrderEntryBusinessLogicHandler :
      Microsoft.SqlServer.Replication.BusinessLogicSupport.BusinessLogicModule
    {
        // Variables to hold server names.
        private string publisherName;
        private string subscriberName;

        public OrderEntryBusinessLogicHandler()
        {
        }

        // Implement the Initialize method to get publication 
        // and subscription information.
        public override void Initialize(
            string publisher,
            string subscriber,
            string distributor,
            string publisherDB,
            string subscriberDB,
            string articleName)
        {
            // Set the Publisher and Subscriber names.
            publisherName = publisher;
            subscriberName = subscriber;
        }

        // Declare what types of row changes, conflicts, or errors to handle.
        override public ChangeStates HandledChangeStates
        {
            get
            {
                // Handle Subscriber inserts, updates and deletes.
                return ChangeStates.SubscriberInserts |
                  ChangeStates.SubscriberUpdates | ChangeStates.SubscriberDeletes;
            }
        }

        public override ActionOnDataChange InsertHandler(SourceIdentifier insertSource,
          DataSet insertedDataSet, ref DataSet customDataSet, ref int historyLogLevel,
          ref string historyLogMessage)
        {
            if (insertSource == SourceIdentifier.SourceIsSubscriber)
            {
                // Build a line item in the audit message to log the Subscriber insert.
                StringBuilder AuditMessage = new StringBuilder();
                AuditMessage.Append(String.Format("A new order was entered at {0}. " +
                  "The SalesOrderID for the order is :", subscriberName));
                AuditMessage.Append(insertedDataSet.Tables[0].Rows[0]["SalesOrderID"].ToString());
                AuditMessage.Append("The order must be shipped by :");
                AuditMessage.Append(insertedDataSet.Tables[0].Rows[0]["DueDate"].ToString());

                // Set the reference parameter to write the line to the log file.
                historyLogMessage = AuditMessage.ToString();
                
                // Set the history log level to the default verbose level.
                historyLogLevel = 1;

                // Accept the inserted data in the Subscriber's data set and 
                // apply it to the Publisher.
                return ActionOnDataChange.AcceptData;
            }
            else
            {
                return base.InsertHandler(insertSource, insertedDataSet, ref customDataSet,
                  ref historyLogLevel, ref historyLogMessage);
            }
        }

        public override ActionOnDataChange UpdateHandler(SourceIdentifier updateSource,
          DataSet updatedDataSet, ref DataSet customDataSet, ref int historyLogLevel,
          ref string historyLogMessage)
        {
            if (updateSource == SourceIdentifier.SourceIsPublisher)
            {
                // Build a line item in the audit message to log the Subscriber update.
                StringBuilder AuditMessage = new StringBuilder();
                AuditMessage.Append(String.Format("An existing order was updated at {0}. " +
                  "The SalesOrderID for the order is ", subscriberName));
                AuditMessage.Append(updatedDataSet.Tables[0].Rows[0]["SalesOrderID"].ToString());
                AuditMessage.Append("The order must now be shipped by :");
                AuditMessage.Append(updatedDataSet.Tables[0].Rows[0]["DueDate"].ToString());

                // Set the reference parameter to write the line to the log file.
                historyLogMessage = AuditMessage.ToString();
                // Set the history log level to the default verbose level.
                historyLogLevel = 1;

                // Accept the updated data in the Subscriber's data set and apply it to the Publisher.
                return ActionOnDataChange.AcceptData;
            }
            else
            {
                return base.UpdateHandler(updateSource, updatedDataSet,
                  ref customDataSet, ref historyLogLevel, ref historyLogMessage);
            }
        }

        public override ActionOnDataDelete DeleteHandler(SourceIdentifier deleteSource,
          DataSet deletedDataSet, ref int historyLogLevel, ref string historyLogMessage)
        {
            if (deleteSource == SourceIdentifier.SourceIsSubscriber)
            {
                // Build a line item in the audit message to log the Subscriber deletes.
                // Note that the rowguid is the only information that is 
                // available in the dataset.
                StringBuilder AuditMessage = new StringBuilder();
                AuditMessage.Append(String.Format("An existing order was deleted at {0}. " +
                  "The rowguid for the order is ", subscriberName));
                AuditMessage.Append(deletedDataSet.Tables[0].Rows[0]["rowguid"].ToString());

                // Set the reference parameter to write the line to the log file.
                historyLogMessage = AuditMessage.ToString();
                // Set the history log level to the default verbose level.
                historyLogLevel = 1;

                // Accept the delete and apply it to the Publisher.
                return ActionOnDataDelete.AcceptDelete;
            }
            else
            {
                return base.DeleteHandler(deleteSource, deletedDataSet,
                  ref historyLogLevel, ref historyLogMessage);
            }
        }
    }
}
Imports System
Imports System.Text
Imports System.Data
Imports System.Data.Common
Imports Microsoft.SqlServer.Replication.BusinessLogicSupport

Namespace Microsoft.Samples.SqlServer.BusinessLogicHandler
    Public Class OrderEntryBusinessLogicHandler
        Inherits BusinessLogicModule

        ' Variables to hold server names.
        Private publisherName As String
        Private subscriberName As String

        ' Implement the Initialize method to get publication 
        ' and subscription information.
        Public Overrides Sub Initialize( _
        ByVal publisher As String, _
        ByVal subscriber As String, _
        ByVal distributor As String, _
        ByVal publisherDB As String, _
        ByVal subscriberDB As String, _
        ByVal articleName As String _
      )
            ' Set the Publisher and Subscriber names.
            publisherName = publisher
            subscriberName = subscriber
        End Sub

        ' Declare what types of row changes, conflicts, or errors to handle.
        Public Overrides ReadOnly Property HandledChangeStates() As ChangeStates
            Get
                ' Handle Subscriber inserts, updates and deletes.
                Return (ChangeStates.SubscriberInserts Or _
                 ChangeStates.SubscriberUpdates Or ChangeStates.SubscriberDeletes)
            End Get
        End Property

        Public Overrides Function InsertHandler(ByVal insertSource As SourceIdentifier, _
        ByVal insertedDataSet As DataSet, ByRef customDataSet As DataSet, _
        ByRef historyLogLevel As Integer, ByRef historyLogMessage As String) _
        As ActionOnDataChange

            If insertSource = SourceIdentifier.SourceIsSubscriber Then
                ' Build a line item in the audit message to log the Subscriber insert.
                Dim AuditMessage As StringBuilder = New StringBuilder()
                AuditMessage.Append(String.Format("A new order was entered at {0}. " + _
                 "The SalesOrderID for the order is :", subscriberName))
                AuditMessage.Append(insertedDataSet.Tables(0).Rows(0)("SalesOrderID").ToString())
                AuditMessage.Append("The order must be shipped by :")
                AuditMessage.Append(insertedDataSet.Tables(0).Rows(0)("DueDate").ToString())

                ' Set the reference parameter to write the line to the log file.
                historyLogMessage = AuditMessage.ToString()

                ' Set the history log level to the default verbose level.
                historyLogLevel = 1

                ' Accept the inserted data in the Subscriber's data set and 
                ' apply it to the Publisher.
                Return ActionOnDataChange.AcceptData
            Else
                Return MyBase.InsertHandler(insertSource, insertedDataSet, customDataSet, _
                 historyLogLevel, historyLogMessage)
            End If
        End Function
        Public Overrides Function UpdateHandler(ByVal updateSource As SourceIdentifier, _
        ByVal updatedDataSet As DataSet, ByRef customDataSet As DataSet, _
        ByRef historyLogLevel As Integer, ByRef historyLogMessage As String) _
        As ActionOnDataChange

            If updateSource = SourceIdentifier.SourceIsPublisher Then
                ' Build a line item in the audit message to log the Subscriber update.
                Dim AuditMessage As StringBuilder = New StringBuilder()
                AuditMessage.Append(String.Format("An existing order was updated at {0}. " + _
                 "The SalesOrderID for the order is ", subscriberName))
                AuditMessage.Append(updatedDataSet.Tables(0).Rows(0)("SalesOrderID").ToString())
                AuditMessage.Append("The order must now be shipped by :")
                AuditMessage.Append(updatedDataSet.Tables(0).Rows(0)("DueDate").ToString())

                ' Set the reference parameter to write the line to the log file.
                historyLogMessage = AuditMessage.ToString()
                ' Set the history log level to the default verbose level.
                historyLogLevel = 1

                ' Accept the updated data in the Subscriber's data set and apply it to the Publisher.
                Return ActionOnDataChange.AcceptData
            Else
                Return MyBase.UpdateHandler(updateSource, updatedDataSet, _
                 customDataSet, historyLogLevel, historyLogMessage)
            End If
        End Function
        Public Overrides Function DeleteHandler(ByVal deleteSource As SourceIdentifier, _
        ByVal deletedDataSet As DataSet, ByRef historyLogLevel As Integer, _
         ByRef historyLogMessage As String) As ActionOnDataDelete
            If deleteSource = SourceIdentifier.SourceIsSubscriber Then
                ' Build a line item in the audit message to log the Subscriber deletes.
                ' Note that the rowguid is the only information that is 
                ' available in the dataset.
                Dim AuditMessage As StringBuilder = New StringBuilder()
                AuditMessage.Append(String.Format("An existing order was deleted at {0}. " + _
                 "The rowguid for the order is ", subscriberName))
                AuditMessage.Append(deletedDataSet.Tables(0).Rows(0)("rowguid").ToString())

                ' Set the reference parameter to write the line to the log file.
                historyLogMessage = AuditMessage.ToString()
                ' Set the history log level to the default verbose level.
                historyLogLevel = 1

                ' Accept the delete and apply it to the Publisher.
                Return ActionOnDataDelete.AcceptDelete
            Else
                Return MyBase.DeleteHandler(deleteSource, deletedDataSet, _
                 historyLogLevel, historyLogMessage)
            End If
        End Function
    End Class
End Namespace

In diesem Beispiel wird ein Geschäftslogikhandler beim Verteiler registriert.This example registers a business logic handler at the Distributor.

// Specify the Distributor name and business logic properties.
string distributorName = publisherInstance;
string assemblyName = @"C:\Program Files\Microsoft SQL Server\110\COM\CustomLogic.dll";
string className = "Microsoft.Samples.SqlServer.BusinessLogicHandler.OrderEntryBusinessLogicHandler";
string friendlyName = "OrderEntryLogic";

ReplicationServer distributor;
BusinessLogicHandler customLogic;

    // Create a connection to the Distributor.
ServerConnection distributorConn = new ServerConnection(distributorName);

try
{
    // Connect to the Distributor.
    distributorConn.Connect();

    // Set the Distributor properties.
    distributor = new ReplicationServer(distributorConn);

    // Set the business logic handler properties.
    customLogic = new BusinessLogicHandler();
    customLogic.DotNetAssemblyName = assemblyName;
    customLogic.DotNetClassName = className;
    customLogic.FriendlyName = friendlyName;
    customLogic.IsDotNetAssembly = true;

    Boolean isRegistered = false;

    // Check if the business logic handler is already registered at the Distributor.
    foreach (BusinessLogicHandler registeredLogic
        in distributor.EnumBusinessLogicHandlers())
    {
        if (registeredLogic == customLogic)
        {
            isRegistered = true;
        }
    }

    // Register the custom logic.
    if (!isRegistered)
    {
        distributor.RegisterBusinessLogicHandler(customLogic);
    }
}
catch (Exception ex)
{
    // Do error handling here.
    throw new ApplicationException(string.Format(
        "The {0} assembly could not be registered.",
        assemblyName), ex);
}
finally
{
    distributorConn.Disconnect();
}
' Specify the Distributor name and business logic properties.
Dim distributorName As String = publisherInstance
Dim assemblyName As String = "C:\Program Files\Microsoft SQL Server\110\COM\CustomLogic.dll"
Dim className As String = "Microsoft.Samples.SqlServer.BusinessLogicHandler.OrderEntryBusinessLogicHandler"
Dim friendlyName As String = "OrderEntryLogic"

Dim distributor As ReplicationServer
Dim customLogic As BusinessLogicHandler

' Create a connection to the Distributor.
Dim distributorConn As ServerConnection = New ServerConnection(distributorName)

Try
    ' Connect to the Distributor.
    distributorConn.Connect()

    ' Set the Distributor properties.
    distributor = New ReplicationServer(distributorConn)

    ' Set the business logic handler properties.
    customLogic = New BusinessLogicHandler()
    customLogic.DotNetAssemblyName = assemblyName
    customLogic.DotNetClassName = className
    customLogic.FriendlyName = friendlyName
    customLogic.IsDotNetAssembly = True

    Dim isRegistered As Boolean = False

    ' Check if the business logic handler is already registered at the Distributor.
    For Each registeredLogic As BusinessLogicHandler _
    In distributor.EnumBusinessLogicHandlers
        If registeredLogic Is customLogic Then
            isRegistered = True
        End If
    Next

    ' Register the custom logic.
    If Not isRegistered Then
        distributor.RegisterBusinessLogicHandler(customLogic)
    End If
Catch ex As Exception
    ' Do error handling here.
    Throw New ApplicationException(String.Format( _
     "The {0} assembly could not be registered.", _
     assemblyName), ex)
Finally
    distributorConn.Disconnect()
End Try

In diesem Beispiel wird ein vorhandener Artikel geändert, um den Geschäftslogikhandler zu verwenden.This example changes an existing article to use the business logic handler.

// Define the Publisher, publication, and article names.
string publisherName = publisherInstance;
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks2012";
string articleName = "SalesOrderHeader";

// Set the friendly name of the business logic handler.
string customLogic = "OrderEntryLogic";

MergeArticle article = new MergeArticle();

// Create a connection to the Publisher.
ServerConnection conn = new ServerConnection(publisherName);

try
{
    // Connect to the Publisher.
    conn.Connect();

    // Set the required properties for the article.
    article.ConnectionContext = conn;
    article.Name = articleName;
    article.DatabaseName = publicationDbName;
    article.PublicationName = publicationName;

    // Load the article properties.
    if (article.LoadProperties())
    {
        article.ArticleResolver = customLogic;
    }
    else
    {
        // Throw an exception of the article does not exist.
        throw new ApplicationException(String.Format(
        "{0} is not published in {1}", articleName, publicationName));
    }
    
}
catch (Exception ex)
{
    // Do error handling here and rollback the transaction.
    throw new ApplicationException(String.Format(
        "The business logic handler {0} could not be associated with " +
        " the {1} article.",customLogic,articleName), ex);
}
finally
{
    conn.Disconnect();
}
' Define the Publisher, publication, and article names.
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2012"
Dim articleName As String = "SalesOrderHeader"

' Set the friendly name of the business logic handler.
Dim customLogic As String = "OrderEntryLogic"

Dim article As MergeArticle = New MergeArticle()

' Create a connection to the Publisher.
Dim conn As ServerConnection = New ServerConnection(publisherName)

Try
    ' Connect to the Publisher.
    conn.Connect()

    ' Set the required properties for the article.
    article.ConnectionContext = conn
    article.Name = articleName
    article.DatabaseName = publicationDbName
    article.PublicationName = publicationName

    ' Load the article properties.
    If article.LoadProperties() Then
        article.ArticleResolver = customLogic
    Else
        ' Throw an exception of the article does not exist.
        Throw New ApplicationException(String.Format( _
         "{0} is not published in {1}", articleName, publicationName))
    End If

Catch ex As Exception
    ' Do error handling here and rollback the transaction.
    Throw New ApplicationException(String.Format( _
     "The business logic handler {0} could not be associated with " + _
     " the {1} article.", customLogic, articleName), ex)
Finally
    conn.Disconnect()
End Try

Weitere InformationenSee Also

Implementieren eines benutzerdefinierten Konfliktlösers für einen Mergeartikel Implement a Custom Conflict Resolver for a Merge Article
Debuggen eines Geschäftslogikhandlers (Replikationsprogrammierung) Debug a Business Logic Handler (Replication Programming)
Replication Security Best Practices Replication Security Best Practices
Replication Management Objects ConceptsReplication Management Objects Concepts