SSDT/VS2015 数据库部署——发布忽略嵌套视图

Posted

技术标签:

【中文标题】SSDT/VS2015 数据库部署——发布忽略嵌套视图【英文标题】:SSDT/ VS2015 Database deployment -- publishing is ignoring nested views 【发布时间】:2016-02-22 21:17:59 【问题描述】:

我正在尝试获取有关 SSDT 数据库开发和部署的一些知识和用例,并努力解决一些部署问题。

特别是在使用嵌套视图时。由于某些未知原因,在尝试将项目中的文件部署/发布到本地/实时数据库时,它似乎弄乱了视图中的引用。

在这个项目中,我有以下观点(示例):

查看1 查看2 查看3

View1 引用 View2,而 View3 正在引用 View1。

构建项目工作正常。但是,当我尝试通过快照生成 dacpac 并将其发布到数据库或让 Visual Studio 在比较模式之后(或不)生成更新脚本来发布数据库时,我最终会得到一个更新脚本,该脚本试图在它们在项目中存储的逻辑顺序似乎是什么。

在这种情况下,View1 -> View2 -> View3。这意味着由于参考问题,发布失败。如果引用的视图不存在,则无法创建视图。

我已经尝试了几个选项,通过以各种方式在项目中添加 dacpac 作为参考(相同的数据库,相同的服务器,不同的数据库 w/w/o 数据库参数),但在许多情况下,我最终会遇到 sql71561 / SQL71508 错误是另一个要解决的 PITA。

我在网上找不到任何好的资源来解释如何解决这个问题或解释它是如何正常工作的。

希望我能在这里得到一些帮助。如果您需要我方面的额外意见或希望我尝试一些事情,请告诉我。

【问题讨论】:

我强烈建议您放弃使用嵌套视图的概念。这似乎完全合乎逻辑,但表现绝对可怕。它会让你的 sql server 崩溃。 simple-talk.com/sql/performance/… 你能放一些演示代码来重现它吗? @seanlange 我想它和大多数东西一样,不是功能,而是你用它做什么:) 每个嵌套视图不会影响性能,但编写复杂查询的成本很高在嵌套视图的情况下可能被隐藏 @SeanLange:我很清楚最佳实践,但是这是目前我们需要处理的情况,是一个临时解决方案。随时对提出的实际问题发表评论。 我不得不用作破解/解决方法的一件事是关闭初始部署的事务,然后回来重新发布数据库。这通常会让第一次发布完成,如果部分不成功,那么一旦创建了父对象,我就可以回来创建适当的视图/过程。除了刚开始使用一组空的数据库之外,我不建议这样做。不过,很高兴您找到了一些解决方法。 【参考方案1】:

问题已通过新的见解得到解决。在尝试构建演示代码以与 SO 社区共享时,我意外地找到了解决方案,因为我需要清理敏感数据(模型)部分。请让我详细说明问题所在。

解决方案可以分为两种解决方案:

数据库项目/解决方案的配置 引用的工作方式

我将就这两件事分享一些见解。

数据库项目/解决方案的配置

Visual Studio 解决方案包含一个项目,其中放置了所有视图。实际表和其他数据库项目在不同的解决方案/项目中分开。

Solution1
  Project1
    View1
    View2
    View3

Solution2
  Project1
    Tables
    Security
    Schemas
    Etc...

视图本身包含由三部分组成的标识符 [Database].[Schema].[Table/View]。这既适用于项目内的项目(视图),也适用于项目外的项目(表等)。

仅使用带有视图的单独项目会导致缺少引用。它无法找到其他视图或表格(进一步参见参考资料)。

此问题的一个解决方案是确保引用的视图和表都在同一个解决方案/项目中。即使使用三部分标识符,Visual Studio 也会忽略这些,因为同一项目/解决方案中存在所有项目。它会以这种方式检测依赖关系。

引用的工作方式

解决它的另一种方法是在 Visual Studio 中以正确的方式使用引用。这是第二种可能的解决方案。

考虑前面的示例,其中视图位于不同的解决方案中,因为其他元素导致缺少引用。但是,使用相同数据库设置添加 dacpac 作为数据库引用会导致引用冲突,并且模型中已经存在 SQL71508 元素。这是真的,因为它存在于引用 dacpac 中,我们尝试在 dacpac 中创建一个同名引用自身的新视图。这是因为它将三部分引用视为 dacpac 的变量。

当对同一服务器、不同数据库使用 dacpac 设置时,它会解析混淆的引用,因为它将三部分标识符视为外部引用,并认为您创建了查看外部 dacpac 的视图的本地副本.换句话说,它不会检测到嵌套视图,因为它认为您引用了一个不在项目内部的单独数据库。

在构建项目时,这不会导致错误,并且可以进行部署。但是,由于它认为您正在引用外部数据源(以 dacpac 的形式),因此它看不到对其他本地视图的引用。

解决方案(至少这对我们有用)是当我们需要对其他视图进行本地引用时,在我们的视图中使用两部分标识符。这样,它将查看项目中的其他文件,而不是引用的 dacpac。

因为它会检测到对其他本地视图的引用,所以它会正确构建并检测本地项目内视图中的依赖关系。然后它将为所有视图创建一个良好的构建顺序。

我想您也可以为引用的 Dacpac 分配不同的变量名称,一直使用三部分标识符,但将外部 dacpac 中的变量更改为使用新分配的变量名称。我们尚未对此进行测试(但我今晚回家时会测试)。

因此,当您使用部分项目或将数据库拆分为多个项目/解决方案时,总而言之,这是一次很好的学习体验,了解数据库引用如何在数据库项目中工作。现在来了解这个潘多拉的黑匣子并将它们转换为面向未来的解决方案:)

【讨论】:

以上是关于SSDT/VS2015 数据库部署——发布忽略嵌套视图的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery next() 并忽略嵌套列表?

JSON Stringify 忽略 Redis 发布上的嵌套对象

在 NestJS 嵌套模式中忽略 @Prop 和 mongoose 选项

如何忽略 Terraform 中的嵌套字段?

Springfox/Swagger 忽略嵌套对象的 @XmlElement 注释

嵌套 Rails 模型 - 创建时忽略 child_index