如何定义合并表项目之间的逻辑记录关系(RMO 编程)

注意注意

后续版本的 Microsoft SQL Server 将删除该功能。 请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。

利用合并复制,您可以定义不同表中的相关行之间的关系。然后就可以在同步过程中将这些行作为一个事务单元进行处理。无论两个项目之间是否存在联接筛选器关系,都可以在这两个项目之间定义逻辑记录。有关详细信息,请参阅通过逻辑记录对相关行的更改进行分组

您可以使用复制管理对象 (RMO) 以编程方式指定项目之间的逻辑记录关系。

注意注意

利用合并复制,您可以指定在逻辑记录级跟踪和解决冲突,但使用 RMO 却无法设置这些选项。有关使用复制存储过程设置这些选项的信息,请参阅如何定义合并表项目之间的逻辑记录关系(复制 Transact-SQL 编程)

在没有关联的联接筛选器的情况下定义逻辑记录关系

  1. 使用 ServerConnection 类创建与发布服务器的连接。

  2. 创建 MergePublication 类的实例,为发布设置 NameDatabaseName 属性并将 ConnectionContext 属性设置为在步骤 1 中创建的连接。

  3. 调用 LoadProperties 方法获取该对象的属性。如果此方法返回 false,则说明步骤 2 中的发布属性定义不正确,或者此发布不存在。

  4. 如果 PartitionGroupsOption 属性设置为 False,请将其设为 True

  5. 如果要构成逻辑记录的项目不存在,请创建 MergeArticle 类的一个实例,然后设置以下属性:

    • Name 设置为项目的名称。

    • PublicationName 设置为发布的名称。

    • (可选)如果对项目进行水平筛选,则将 FilterClause 属性指定为行筛选器子句。使用此属性可指定静态行筛选器或参数化行筛选器。有关详细信息,请参阅参数化行筛选器

    有关详细信息,请参阅如何定义项目(RMO 编程)

  6. 调用 Create 方法。

  7. 对构成逻辑记录的每个项目,重复执行步骤 5 和 6。

  8. 创建 MergeJoinFilter 类的一个实例以定义项目之间的逻辑记录关系。然后,设置以下属性:

  9. 对表示此关系中的子项目的对象调用 AddMergeJoinFilter 方法。传递步骤 8 中的 MergeJoinFilter 对象以定义此关系。

  10. 对发布中的其余每个逻辑记录关系重复执行步骤 8 和 9。

示例

此示例为 SalesOrderHeaderSalesOrderDetail 表创建一个由两个新项目构成的逻辑记录。

// Define the Publisher and publication names.
string publisherName = publisherInstance;
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks";

// Specify article names.
string articleName1 = "SalesOrderHeader";
string articleName2 = "SalesOrderDetail";

// Specify logical record information.
string lrName = "SalesOrderHeader_SalesOrderDetail";
string lrClause = "[SalesOrderHeader].[SalesOrderID] = "
    + "[SalesOrderDetail].[SalesOrderID]";

string schema = "Sales";

MergeArticle article1 = new MergeArticle();
MergeArticle article2 = new MergeArticle();
MergeJoinFilter lr = new MergeJoinFilter();
MergePublication publication = new MergePublication();

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

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

    // Verify that the publication uses precomputed partitions.
    publication.Name = publicationName;
    publication.DatabaseName = publicationDbName;
    publication.ConnectionContext = conn;

    // If we can't get the properties for this merge publication, then throw an application exception.
    if (publication.LoadProperties())
    {
        // If precomputed partitions is disabled, enable it.
        if (publication.PartitionGroupsOption == PartitionGroupsOption.False)
        {
            publication.PartitionGroupsOption = PartitionGroupsOption.True;
        }
    }
    else
    {
        throw new ApplicationException(String.Format(
            "Settings could not be retrieved for the publication. " +
            "Ensure that the publication {0} exists on {1}.",
            publicationName, publisherName));
    }

    // Set the required properties for the PurchaseOrderHeader article.
    article1.ConnectionContext = conn;
    article1.Name = articleName1;
    article1.DatabaseName = publicationDbName;
    article1.SourceObjectName = articleName1;
    article1.SourceObjectOwner = schema;
    article1.PublicationName = publicationName;
    article1.Type = ArticleOptions.TableBased;

    // Set the required properties for the SalesOrderDetail article.
    article2.ConnectionContext = conn;
    article2.Name = articleName2;
    article2.DatabaseName = publicationDbName;
    article2.SourceObjectName = articleName2;
    article2.SourceObjectOwner = schema;
    article2.PublicationName = publicationName;
    article2.Type = ArticleOptions.TableBased;

    if (!article1.IsExistingObject) article1.Create();
    if (!article2.IsExistingObject) article2.Create();

    // Define a logical record relationship between 
    // PurchaseOrderHeader and PurchaseOrderDetail. 

    // Parent article.
    lr.JoinArticleName = articleName1;

    // Child article.
    lr.ArticleName = articleName2;
    lr.FilterName = lrName;
    lr.JoinUniqueKey = true;
    lr.FilterTypes = FilterTypes.LogicalRecordLink;
    lr.JoinFilterClause = lrClause;

    // Add the logical record definition to the parent article.
    article1.AddMergeJoinFilter(lr);
}
catch (Exception ex)
{
    // Do error handling here and rollback the transaction.
    throw new ApplicationException(
        "The filtered articles could not be created", ex);
}
finally
{
    conn.Disconnect();
}
' Define the Publisher and publication names.
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks"

' Specify article names.
Dim articleName1 As String = "SalesOrderHeader"
Dim articleName2 As String = "SalesOrderDetail"

' Specify logical record information.
Dim lrName As String = "SalesOrderHeader_SalesOrderDetail"
Dim lrClause As String = "[SalesOrderHeader].[SalesOrderID] = " _
        & "[SalesOrderDetail].[SalesOrderID]"

Dim schema As String = "Sales"

Dim article1 As MergeArticle = New MergeArticle()
Dim article2 As MergeArticle = New MergeArticle()
Dim lr As MergeJoinFilter = New MergeJoinFilter()
Dim publication As MergePublication = New MergePublication()

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

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

    ' Verify that the publication uses precomputed partitions.
    publication.Name = publicationName
    publication.DatabaseName = publicationDbName
    publication.ConnectionContext = conn

    ' If we can't get the properties for this merge publication, then throw an application exception.
    If publication.LoadProperties() Then
        ' If precomputed partitions is disabled, enable it.
        If publication.PartitionGroupsOption = PartitionGroupsOption.False Then
            publication.PartitionGroupsOption = PartitionGroupsOption.True
        End If
    Else
        Throw New ApplicationException(String.Format( _
            "Settings could not be retrieved for the publication. " _
            & "Ensure that the publication {0} exists on {1}.", _
            publicationName, publisherName))
    End If

    ' Set the required properties for the SalesOrderHeader article.
    article1.ConnectionContext = conn
    article1.Name = articleName1
    article1.DatabaseName = publicationDbName
    article1.SourceObjectName = articleName1
    article1.SourceObjectOwner = schema
    article1.PublicationName = publicationName
    article1.Type = ArticleOptions.TableBased

    ' Set the required properties for the SalesOrderDetail article.
    article2.ConnectionContext = conn
    article2.Name = articleName2
    article2.DatabaseName = publicationDbName
    article2.SourceObjectName = articleName2
    article2.SourceObjectOwner = schema
    article2.PublicationName = publicationName
    article2.Type = ArticleOptions.TableBased

    If Not article1.IsExistingObject Then
        article1.Create()
    End If
    If Not article2.IsExistingObject Then
        article2.Create()
    End If

    ' Define a logical record relationship between 
    ' SalesOrderHeader and SalesOrderDetail. 

    ' Parent article.
    lr.JoinArticleName = articleName1
    ' Child article.
    lr.ArticleName = articleName2
    lr.FilterName = lrName
    lr.JoinUniqueKey = True
    lr.FilterTypes = FilterTypes.LogicalRecordLink
    lr.JoinFilterClause = lrClause

    ' Add the logical record definition to the parent article.
    article1.AddMergeJoinFilter(lr)
Catch ex As Exception
    ' Do error handling here and rollback the transaction.
    Throw New ApplicationException( _
            "The filtered articles could not be created", ex)
Finally
    conn.Disconnect()
End Try