尝试同步数据库时出现DbProvisioningException

时间:2015-04-26 21:42:14

标签: c# sql-server provisioning microsoft-sync-framework

我一直在关注MSDN上的这个指南:https://msdn.microsoft.com/en-us/library/ff928700(v=sql.110).aspx

这是我的代码:

public void ProvisionServer()
    {
        SqlConnection serverConn = (SqlConnection) _serverConn.Create();
        DbSyncScopeDescription scopeDesc = new DbSyncScopeDescription(_sScope);

        DbSyncTableDescription listDesc = SqlSyncDescriptionBuilder.GetDescriptionForTable("List", serverConn);
        scopeDesc.Tables.Add(listDesc);
        DbSyncTableDescription itemDesc = SqlSyncDescriptionBuilder.GetDescriptionForTable("Item", serverConn);
        scopeDesc.Tables.Add(itemDesc);
        DbSyncTableDescription listItemDesc = SqlSyncDescriptionBuilder.GetDescriptionForTable("ListItem", serverConn);
        scopeDesc.Tables.Add(listItemDesc);

        SqlSyncScopeProvisioning serverProvision = new SqlSyncScopeProvisioning(serverConn,scopeDesc);
        serverProvision.SetCreateTableDefault(DbSyncCreationOption.Skip);

        serverProvision.Apply();
    }

    public void ProvisionClient()
    {
        SqlConnection clientConn = (SqlConnection)_clientConn.Create();
        SqlConnection serverConn = (SqlConnection) _serverConn.Create();

        DbSyncScopeDescription scopeDesc = SqlSyncDescriptionBuilder.GetDescriptionForScope(_sScope, serverConn);
        SqlSyncScopeProvisioning clientProvision = new SqlSyncScopeProvisioning(clientConn,scopeDesc);

        clientProvision.Apply();
    }

    public void Sync()
    {
        SqlConnection clientConn = (SqlConnection)_clientConn.Create();
        SqlConnection serverConn = (SqlConnection)_serverConn.Create();

        SyncOrchestrator syncOrchestrator = new SyncOrchestrator();

        syncOrchestrator.LocalProvider = new SqlSyncProvider(_sScope, clientConn);
        syncOrchestrator.RemoteProvider = new SqlSyncProvider(_sScope,serverConn);

        syncOrchestrator.Direction = SyncDirectionOrder.DownloadAndUpload;

        ((SqlSyncProvider)syncOrchestrator.LocalProvider).ApplyChangeFailed += Program_ApplyChangeFailed;

        SyncOperationStatistics syncStats = syncOrchestrator.Synchronize();

        Console.WriteLine("Start Time: " + syncStats.SyncStartTime);
        Console.WriteLine("Total Changes Uploaded: " + syncStats.UploadChangesTotal);
        Console.WriteLine("Total Changes Downloaded: " + syncStats.DownloadChangesTotal);
        Console.WriteLine("Complete Time: " + syncStats.SyncEndTime);
        Console.WriteLine(String.Empty);
    }

    public void Program_ApplyChangeFailed(object sender, DbApplyChangeFailedEventArgs e)
    {           
        Console.WriteLine(e.Conflict.Type);
        Console.WriteLine(e.Error);
    }

我的ConnectionFactory:

public class AppConnectionFactory : IConnectionFactory
{
    private readonly DbProviderFactory _provider;
    private readonly string _connectionString;
    private readonly string _name;

    public AppConnectionFactory(string connectionName)
    {
        if (connectionName == null)
            throw new ArgumentNullException("connectionName");

        var connStr = ConfigurationManager.ConnectionStrings[connectionName];
        if (connStr == null)
            throw new ConfigurationErrorsException(string.Format("Failed to find the connection named {0} in App.config",connectionName));

        _name = connStr.ProviderName;
        _provider = DbProviderFactories.GetFactory(connStr.ProviderName);
        _connectionString = connStr.ConnectionString;
    }

    public IDbConnection Create()
    {
        var connection = _provider.CreateConnection();
        connection.ConnectionString = _connectionString;
        connection.Open();
        return connection;
    }

}

我的测试:

static void Main(string[] args)
    {
        var serverConn = new AppConnectionFactory("SmartFridgeConn");
        var clientConn = new AppConnectionFactory("SmartfridgeConn");
        var sync = new DbSync(serverConn,clientConn);
        sync.ProvisionServer();
        sync.ProvisionClient();
        sync.Sync();
    }

但是Sync.ProvisionClient();会抛出一个DbProvisioningException,其中包含以下信息:“无法创建名称为'SmartFridgeScope'的作用域作为具有该名称的作用域。”

我错过了什么,还是我完全错了?提前谢谢。

1 个答案:

答案 0 :(得分:1)

每次尝试同步时都要尝试配置。如果您对配置的调用是为了确保在执行同步之前已配置范围,请在配置之前调用ScopeExists()以检查范围是否已存在。