我刚刚使用上述答案编写了一个命令行程序,用于在 c# 中执行此操作
并认为我会扩展上面的答案。
如果你想输出数据以及你需要使用的架构:
scripter.EnumScript(something);
//instead of
scripter.Script(something);
脚本方法只是检查 IncludeData 选项,如果设置了它就会抛出异常,但你必须上 google 才能找到正确的方法!有趣的 API 设计!
数据库中的相关列表如下:
database.Tables
database.Schemas
database.Views
database.StoredProcedures
database.UserDefinedFunctions
database.Users
database.Roles
database.Sequences
虽然这可能并不详尽。
摆脱系统对象
这些对象中的列表都是IEnumerable but not IEnumerable<T> 的自定义类型,因此您不能对它们执行linq。这也意味着您必须找出其中的类型并使用 foreach 的隐式强制转换将它们取出。我以前从未在 c# 中使用过它,但我猜这东西可能是针对框架 2。
其中很多也有称为 IsSystemObject 的属性,但这并没有实现接口。起初,摆脱所有系统对象看起来会很痛苦,但您可以通过设置以下选项一举将它们全部剔除:
options.AllowSystemObjects = false;
这适用于除角色之外的所有内容,您必须手动执行系统角色:
foreach (DatabaseRole role in database.Roles)
{
if(role.IsFixedRole)
continue;
list.Add(role);
}
为输出添加对象
我使用的过程是创建一个 UrnCollection,然后将不同的列表添加到集合中。像这样:
var list = new UrnCollection();
foreach (Schema schema in database.Schemas)
list.Add(schema.Urn);
//... more of these
scripter.EnumScript(list);
选项
从那里你需要弄清楚要设置哪些选项来重新创建你需要的输出。需要注意的几点:
- 索引、触发器、约束等由选项设置,不被视为第一类对象。
- 在 SSMS 的 UI 中,您根本无法生成序列,因此如果您使用这些序列,您的输出中至少会出现一些差异
有关如何获取外键等的更多信息,请参阅this post。
健康警告
我开始将其视为复制数据库的一种方式,因为我认为备份和恢复不会达到我想要的效果。在沿着 smo 路径走了很长一段路并遇到了很多问题之后,我进行了一些重新评估,并找到了backup and restore is a lot simpler for that use case。