SQL数据库项目:根据构建配置构建不同的脚本

时间:2013-02-27 16:32:05

标签: visual-studio-2012 msbuild database-project sql-server-data-tools msbuild-target

我想解决的问题是根据构建配置构建不同的脚本。

假设我们有两个SQL Server实例:

  • 已连接的已关联服务器的企业版
  • 用于离线开发和单元测试的LocalDb版本

当LocalDB使用本地表替换这些视图时,企业版具有链接服务器的视图。

这些链接服务器视图和本地表具有相同的名称和字段集。 因此默认情况下它们不包含在构建中(Build Action = None)。 相反,它们包含在项目文件的BeforeBuild Target中。

<Target Name="BeforeBuild">

    <ItemGroup Condition=" '$(Configuration)' == 'LocalDb'">
        <Build Include="Local_Tables\*.sql" />
    </ItemGroup> 

    <ItemGroup Condition=" '$(Configuration)' != 'LocalDb' ">
        <Build Include="Linked_Server_Views\*.sql" />
    </ItemGroup>

</Target>

但问题是Visual Studio缓存数据库模型,如果我们首先为LocalDb构建项目,然后尝试构建企业配置项目 - Visual Studio输出错误:

错误:SQL71508:模型已经有一个具有相同名称的元素

如果要关闭并打开解决方案或卸载项目和重新加载项目,Visual Studio将重新创建dbmdl文件,并且正在构建企业配置而不会出现错误。

所以我的假设是,如果我刷新dbmdl缓存,我将得到平滑的构​​建而没有错误。


在Visual Studio 2012中打开或重新加载SQL Server数据库项目时,它会创建一个扩展名为 dbmdl 的文件,这是一个反序列化和缓存的数据库模型,如here所述。

在dbmdl文件重新创建的那一刻,Visual Studio将输出以下内容:

Deserializing the project state for project 'MyProject.sqlproj'...
Detecting file changes for project 'MyProject.sqlproj'...
Deserialization has been completed for project 'MyProject.sqlproj'.

如何在没有项目重新加载且不更改项目xml文件的情况下强制Visual Studio刷新dbmdl缓存?

有没有办法刷新dbmdl缓存,将命令放入项目xml文件的BeforeBuild或AfterBuild目标?

或者问题的整个方法是错误的,还有另一种方法可以根据构建配置构建不同的脚本吗?

2 个答案:

答案 0 :(得分:4)

您可能在使用复合项目时有另一种选择。 Jamie Thompson在这里发表了关于他们的博文:http://sqlblog.com/blogs/jamie_thomson/archive/2013/03/10/deployment-of-client-specific-database-code-using-ssdt.aspx

这将允许您构建一个主项目,并使用特定于环境的代码绑定其他项目。您可以通过在发布脚本中执行一些检查来部署适当的一个。

答案 1 :(得分:1)

我正在考虑这个以及使用SSDT处理它的最佳方法。我可能没有“最好”的方式,如果你能在发布更改之前确定正确的版本,我会考虑这个:

  1. 为每个版本创建发布配置文件 - 包含和不包含链接服务器。
  2. 创建变量以保存链接服务器名称,可能还包括数据库,例如“[Server]。[Database]。”
  3. 为链接服务器视图创建部署后脚本。这些应包括权限,链接服务器名称的变量等。
  4. 在Post-Deploy脚本中,查询“edition”变量。如果它将使用链接服务器,则删除/重新创建项目中的本机非链接服务器视图以使用链接服务器上的视图。或者,将变量设置为本地视图的空字符串和链接服务器的服务器/ DB,您可以只使用一组代码。
  5. 这样做的缺点是无法对您的视图进行代码检查,但会为您提供一个位置来存储这些链接的服务器视图以及从中部署它们的位置。您需要使用Drop / Create进行发布,而不是让SSDT处理更改,这意味着它们将在每个Publish操作上重新创建。不过,我认为它可能会为您提供所需的解决方案。