Creating and Running Merge Replication Programmatically

Let me preface this by saying that now I understand how stupid and right I am. I have been developing for 1 year (per day), and this was the first thing I wrote. I have now returned to him, and I cannot make heads or tails. It worked at one point in a very simple application, but that was recently.

In particular, I am having problems with LocalDBConnthat which uses out, but for the life of me I cannot remember why.

Guide, pointer, refactoring, patting on the sides of the head are welcome and welcome!

public class MergeRepl
{
            // Declare nessesary variables
    private string subscriberName;
    private string publisherName;
    private string publicationName;
    private string subscriptionDbName;
    private string publicationDbName;
    private MergePullSubscription mergeSubscription;
    private MergePublication mergePublication;
    private ServerConnection subscriberConn;
    private ServerConnection publisherConn;
    private Server theLocalSQLServer;
    private ReplicationDatabase localRepDB;

    public MergeRepl(string subscriber, string publisher, string publication, string subscriptionDB, string publicationDB)
    {
        subscriberName = subscriber;
        publisherName = publisher;
        publicationName = publication;
        subscriptionDbName = subscriptionDB;
        publicationDbName = publicationDB;

        //Create connections to the Publisher and Subscriber.
        subscriberConn = new ServerConnection(subscriberName);
        publisherConn = new ServerConnection(publisherName);


        // Define the pull mergeSubscription
        mergeSubscription = new MergePullSubscription
                                {
                                    ConnectionContext = subscriberConn,
                                    DatabaseName = subscriptionDbName,
                                    PublisherName = publisherName,
                                    PublicationDBName = publicationDbName,
                                    PublicationName = publicationName
                                };

        // Ensure that the publication exists and that it supports pull subscriptions.
        mergePublication = new MergePublication
                               {
                                   Name = publicationName,
                                   DatabaseName = publicationDbName,
                                   ConnectionContext = publisherConn
                               };

        // Create the local SQL Server instance
        theLocalSQLServer = new Server(subscriberConn);
        // Create a Replication DB Object to initiate Replication settings on local DB
        localRepDB = new ReplicationDatabase(subscriptionDbName, subscriberConn);

        // Check that the database exists locally
        CreateDatabase(subscriptionDbName);
    }

    public void RunDataSync()
    {
        // Keep program from appearing 'Not Responding'
        ///// Application.DoEvents();

        // Does the needed Databases exist on local SQLExpress Install
        /////CreateDatabase("ContactDB");

        try
        {
                 //  Connect to the Subscriber
                 subscriberConn.Connect();

            // if the Subscription exists, then start the sync
                 if (mergeSubscription.LoadProperties())
                 {
                     // Check that we have enough metadata to start the agent
                     if (mergeSubscription.PublisherSecurity != null || mergeSubscription.DistributorSecurity != null)
                     {
                         //  Synchronously start the merge Agent for the mergeSubscription
                         //  lblStatus.Text = "Data Sync Started - Please Be Patient!";
                         mergeSubscription.SynchronizationAgent.Synchronize();
                     }
                     else
                     {
                         throw new ApplicationException("There is insufficient metadata to synchronize the subscription." +
                             "Recreate the subscription with the agent job or supply the required agent properties at run time.");
                     }
                 }
                 else
                 {
                     // do something here if the pull mergeSubscription does not exist
                     // throw new ApplicationException(String.Format("A mergeSubscription to '{0}' does not exist on {1}", publicationName, subscriberName));
                     CreateMergeSubscription();
                 }
        }
        catch (Exception ex)
        {
            // Implement appropriaate error handling here
            throw new ApplicationException("The subscription could not be synchronized.  Verify that the subscription has been defined correctly.", ex);
            //CreateMergeSubscription();
        }
        finally
        {
            subscriberConn.Disconnect();
        }
    }

    public void CreateMergeSubscription()
    {
        // Keep program from appearing 'Not Responding'
        // Application.DoEvents();

        try
        {

            if (mergePublication.LoadProperties())
            {
                if ((mergePublication.Attributes & PublicationAttributes.AllowPull) == 0)
                {
                    mergePublication.Attributes |= PublicationAttributes.AllowPull;
                }

                // Make sure that the agent job for the mergeSubscription is created.
                mergeSubscription.CreateSyncAgentByDefault = true;

                // Create the pull mergeSubscription at the Subscriber.
                mergeSubscription.Create();

                Boolean registered = false;

                // Verify that the mergeSubscription is not already registered.
                foreach (MergeSubscription existing in mergePublication.EnumSubscriptions())
                {
                    if (existing.SubscriberName == subscriberName
                        && existing.SubscriptionDBName == subscriptionDbName
                        && existing.SubscriptionType == SubscriptionOption.Pull)
                    {
                        registered = true;
                    }
                }
                if (!registered)
                {
                    // Register the local mergeSubscription with the Publisher.
                    mergePublication.MakePullSubscriptionWellKnown(
                        subscriberName, subscriptionDbName,
                        SubscriptionSyncType.Automatic,
                        MergeSubscriberType.Local, 0);
                }
            }
            else
            {
                // Do something here if the publication does not exist.
                throw new ApplicationException(String.Format(
                    "The publication '{0}' does not exist on {1}.",
                    publicationName, publisherName));
            }
        }
        catch (Exception ex)
        {
            // Implement the appropriate error handling here.
            throw new ApplicationException(String.Format("The subscription to {0} could not be created.", publicationName), ex);

        }
        finally
        {
            publisherConn.Disconnect();
        }
    }

    /// <summary>
    /// This will make sure the needed DataBase exists locally before allowing any interaction with it.
    /// </summary>
    /// <param name="whichDataBase">The name of the DataBase to check for.</param>
    /// <returns>True if the specified DataBase exists, False if it doesn't.</returns>
     public void CreateDatabase(string whichDataBase)
    {
        Database db;
        LocalDBConn(whichDataBase, out theLocalSQLServer, out localRepDB, out db);


        if (!theLocalSQLServer.Databases.Contains(whichDataBase))
        {
            //Application.DoEvents();
            // Create the database on the instance of SQL Server.
            db = new Database(theLocalSQLServer, whichDataBase);
            db.Create();

        }

        localRepDB.Load();
        localRepDB.EnabledMergePublishing = false;
        localRepDB.CommitPropertyChanges();

        if (!mergeSubscription.LoadProperties())
        {
            CreateMergeSubscription();
        }

    }

    private void LocalDBConn(string databaseName, out Server server, out ReplicationDatabase replicationDatabase, out Database db)
    {
        db = server.Databases[replicationDatabase.Name];
    }

    /// <summary>
    /// Checks for the existince of the Publication.  If there is one it verify Allow Pull is set
    /// </summary>
    /// <returns>True if Publication is present. False if not.</returns>
    public bool CheckForPublication()
    {
        // If LoadProperties() returns TRUE then the Publication exists and is reachable
        if (mergePublication.LoadProperties())
            return true;

        if ((mergePublication.Attributes & PublicationAttributes.AllowPull) == 0)
        {
            mergePublication.Attributes |= PublicationAttributes.AllowPull;
        }

        return false;
    } // end CheckForPublication()

    /// <summary>
    /// Checks for the existence of a Subscription.
    /// </summary>
    /// <returns>True if a Subscription is present.  False if not</returns>
    public bool CheckForSubscription()
    {
        // Check for the existence of the Subscription
        return mergeSubscription.IsExistingObject;
    } // end CheckForSubscription()
}

Change 1

Opps, I forgot specific errors. In serverand replicationDatabaseI get the parameter "Out", which cannot be initialized before accessing

        private void LocalDBConn(string databaseName, out Server server, out ReplicationDatabase replicationDatabase, out Database db)
    {
        db = server.Databases[replicationDatabase.Name];
    }
+3
3

, , out.

, , , , VS2003, .

MSDN: , , , .

private void LocalDBConn(string databaseName, Server server, 
      ReplicationDatabase replicationDatabase, out Database db)
{
    db = server.Databases[replicationDatabase.Name];
}

private Database LocalDBConn(string databaseName, Server server, 
     ReplicationDatabase replicationDatabase)
{
    return server.Databases[replicationDatabase.Name];
}

CreateDatabase, :

Database db;
LocalDBConn(whichDataBase, theLocalSQLServer, localRepDB, out db);

Database db = LocalDBConn(whichDataBase, theLocalSQLServer, localRepDB);
+2
private void LocalDBConn(string databaseName, out Server server, out ReplicationDatabase replicationDatabase, out Database db)
{
    db = server.Databases[replicationDatabase.Name];
}

, . out , (, ). , out , : " " . LocalDBConn .

# 3.0 5.1.6.

+2

, ReplicationDatabase , , LocalDBConn.

, , , .

+1

Source: https://habr.com/ru/post/1709626/


All Articles