如何将参数传递给Microsoft Sync 2.1生成的存储过程

我正在使用Microsoft同步框架2.1版本

我们试图实现数据库版本控制,也就是说,如果服务器数据库中存在表格模式更改,则所有或某些客户端应该仍能够在不进行相同模式更改或不更新数据库的情况下同步其数据。 在更高层次上,我们需要为同一服务器数据库的不同客户端维护多个应用程序版本。

我试图将应用程序版本作为参数传递给所有存储过程,以便我可以处理多个客户端的数据版本。 我能够将参数传递给“select_chagnes”存储过程..但我的问题是如何将版本号传递给所有同步生成的存储过程,以便在所有同步生成的过程中生成参数@version。

要么

欢迎任何维护客户端特定数据的建议,我们的主要目标是允许现有客户端同步他们的数据库,而不需要更新最新的数据库。 这样我们可以让客户端拥有多个指向相同服务器数据库的应用程序版本。


备注如果您删除由旧客户端供应的列或表,则我所用的解决方案不起作用。 如果你想删除你需要做的是多个阶段的列。 首先将所有人升级到版本1.如果所有客户端都升级了,则可以删除列和表。

可能的方案

如果我理解得很好,您希望有一个范围或模板具有多个配置配置。

YourScope:

  • (版本1)
  • 表1(ColumnA,ColumnB)
  • (版本2)
  • 表1(ColumnA,ColumnB,NewColumnC)
  • NewTable2(ColumnX,ColumnY,ColumnZ)
  • 在我看来最好使用:

    Version1_YourScope:

  • 表1(ColumnA,ColumnB)
  • Version2_YourScope:

  • 表1(ColumnA,ColumnB,NewColumnC)
  • NewTable2(ColumnX Columny ColumnZ)
  • 因此,在这种情况下,你不必处理同步框架程序版本,现在你需要通过给客户正确的一组正确范围之外处理的版本。

    该怎么办:

    这一更改在供应期间需要进行一些更改。 让范围相互重叠会产生一些问题:

  • 您必须具有两个用于Table1的BulkTypes(1个不包含NewColumnC,1个包含此新列)
  • 您必须对Table1有两个选择更改
  • Table1必须有两个BulkInsert sp
  • 您希望只有一组Table1的触发器
  • 您希望只有一个Table1跟踪表
  • ...
  • 在配置期间,您可能使用SqlSyncScopeProvider.Apply() 。 还有一个函数返回脚本而不是应用脚本: SqlSyncScopeProvider.Script() 。 这将返回供应脚本。

    所以你可以做这样的事情:

    1:使用以下配置设置使重叠范围成为可能:

    _scopeProvisioning.SetCreateProceduresForAdditionalScopeDefault(DbSyncCreationOption.Create);
    _scopeProvisioning.SetCreateTableDefault(DbSyncCreationOption.Skip);
    _scopeProvisioning.SetCreateProceduresDefault(DbSyncCreationOption.CreateOrUseExisting);
    _scopeProvisioning.SetCreateTrackingTableDefault(DbSyncCreationOption.CreateOrUseExisting);
    _scopeProvisioning.SetCreateTriggersDefault(DbSyncCreationOption.CreateOrUseExisting);
    

    2:获取供应脚本

    var builder = new StringBuilder(_scopeProvisioning.Script());
    

    3:对于每个表,将<tablename>_<procedure/bulktype>重命名为<scopename>_<tablename>_<procedure/bulktype>

    // Rename <tablename>_selectchanges to <scopename>_<tablename>_selectchanges and also all other stored procedures and bulk type
    builder = builder.Replace(String.Format("CREATE PROCEDURE [{0}_selectchanges", table.Name), String.Format("CREATE PROCEDURE [sync].[{1}_{0}_selectchanges", table.Name, scope.Name));
    builder = builder.Replace(String.Format("SelChngProc="[{0}_selectchanges", table.Name), String.Format("SelChngProc="[sync].[{1}_{0}_selectchanges", table.Name, scope.Name));
    builder = builder.Replace(String.Format("[{0}_BulkType]", table.Name), String.Format("[{1}_{0}_BulkType]", table.Name, scope.Name));
    builder = builder.Replace(String.Format("[{0}_selectrow]", table.Name), String.Format("[{1}_{0}_selectrow]", table.Name, scope.Name));
    builder = builder.Replace(String.Format("[{0}_insert]", table.Name), String.Format("[{1}_{0}_insert]", table.Name, scope.Name));
    builder = builder.Replace(String.Format("[{0}_update]", table.Name), String.Format("[{1}_{0}_update]", table.Name, scope.Name));
    builder = builder.Replace(String.Format("[{0}_delete]", table.Name), String.Format("[{1}_{0}_delete]", table.Name, scope.Name));
    builder = builder.Replace(String.Format("[{0}_insertmetadata]", table.Name), String.Format("[{1}_{0}_insertmetadata]", table.Name, scope.Name));
    builder = builder.Replace(String.Format("[{0}_updatemetadata]", table.Name), String.Format("[{1}_{0}_updatemetadata]", table.Name, scope.Name));
    builder = builder.Replace(String.Format("[{0}_deletemetadata]", table.Name), String.Format("[{1}_{0}_deletemetadata]", table.Name, scope.Name));
    builder = builder.Replace(String.Format("[{0}_bulkinsert]", table.Name), String.Format("[{1}_{0}_bulkinsert]", table.Name, scope.Name));
    builder = builder.Replace(String.Format("[{0}_bulkupdate]", table.Name), String.Format("[{1}_{0}_bulkupdate]", table.Name, scope.Name));
    builder = builder.Replace(String.Format("[{0}_bulkdelete]", table.Name), String.Format("[{1}_{0}_bulkdelete]", table.Name, scope.Name));
    

    4:对于与已有范围重叠的每个表,将CREATE TRIGGER更改为ALTER TRIGGER,因为它们已存在于数据库中

    builder = builder.Replace(String.Format("CREATE TRIGGER [{0}_insert_trigger]", table.Name), String.Format("ALTER TRIGGER [{0}_insert_trigger]", table.Name));
    builder = builder.Replace(String.Format("CREATE TRIGGER [{0}_update_trigger]", table.Name), String.Format("ALTER TRIGGER [{0}_update_trigger]", table.Name));
    builder = builder.Replace(String.Format("CREATE TRIGGER [{0}_delete_trigger]", table.Name), String.Format("ALTER TRIGGER [{0}_delete_trigger]", table.Name));
    

    5:执行新的脚本。 请注意,该脚本包含很多GO语句。 您需要在一个SqlCommand中执行两个GO之间的所有内容。

    string[] seperatedScript = GetProvisionScriptSplittedOnGOstatement(builder.ToString);
    foreach(string command in seperatedScript)
    {
       new SqlCommand(command, connection).ExecuteNonQuery(); 
      // make sure you dispose SqlCommand correctly. Not in this example
    }
    

    6:确保老客户规定 Version1_YourScope客户和新客户规定Version2_YourScope所以客户端有多个版本之间没有重叠。

    如果因为要传递过滤参数而使用模板,则需要注意以下几点:

  • 在多个作用域中提到的表的不同过滤列会导致问题,因为触发器不知道使用多个过滤列的多个作用域
  • 配置新的过滤列需要在已有的跟踪表中添加一个新列
  • 祝你好运!

    链接地址: http://www.djcxy.com/p/71591.html

    上一篇: How to pass parameter to Microsoft Sync 2.1 generated Stored procedures

    下一篇: Exceeding the 2GB file upload limitation in IIS 7.5 and .NET