无法获取EnumScript()以生成约束

本教程将介绍无法获取EnumScript()以生成约束的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

无法获取EnumScript()以生成约束 教程 第1张

问题描述

我正在尝试通过编程方式获取我可以使用任务>生成脚本从SSMS手动获取的内容

下面的代码运行良好,只是它不会生成任何约束。我没有得到任何ALTER TABLE [foo] ADD CONSTRAINT ... ON DELETE CASCADE等。我已经尝试了很多Dri选项的组合,也在不同的数据库上尝试过。我被难住了。

感谢您的真知灼见!

  Scripter scrp = new Scripter(srv)
  {
Options =
{
 ScriptDrops = false,
 WithDependencies = false,
 Indexes = true,
 Triggers = false,
 Default = true,
 DriAll = true,
 //ScriptData = true,
 ScriptSchema = true,
}
  };

  var urns = new List<Urn>();

  foreach (Table tb in db.Tables)
  {
if (tb.IsSystemObject == false)
{
 urns.Add(tb.Urn);
}
  }

  var inserts = scrp.EnumScript(urns.ToArray());
  File.WriteAllLines(path, inserts);

推荐答案

我找到了一个解决方案,即使用每个对象的Script方法生成架构,使用EnumScript方法(使用scriptSchema=false)生成表内容的插入。

  foreach (Table tb in db.Tables)
  {
if (tb.IsSystemObject == false)
{
 foreach (var s in tb.Script(schemaOptions))
  strings.Add(s);

 if (scriptData)
 {
  foreach (var i in tb.EnumScript(insertOptions))
strings.Add(i);
 }
}
  }

我承认这个解决方案感觉有点空洞,因为我从来没有发现原来的方法为什么不起作用。这是一种没有诊断的修复,但尽管如此,它仍然是一种修复。

至于我最初为什么要写这个东西,我的数据库在共享服务器上,没有任何方法可以获得可以脱机或在其他地方使用的自动备份。这就是我的备份方案。

上面的解决方案遵循Microsoft在这里给出的代码示例:Scripting。这种方法的问题是,表的脚本编写没有特定的顺序,但是为了定义约束和插入行,需要按照它们的依赖关系的顺序编写脚本。无法引用尚不存在的表中的外键。

到目前为止,我拥有的最佳解决方案是使用DependencyWalker.DiscoverDependencies()获取
依赖关系树,DependencyWalker.WalkDependencies()获取线性列表并迭代该列表,如下所示:

  var urns = new List<Urn>();
  Scripter schemaScripter = new Scripter(srv) { Options = schemaOptions };
  Scripter insertScripter = new Scripter(srv) { Options = insertOptions };
  var dw = new DependencyWalker(srv);

  foreach (Table t in db.Tables)
if (t.IsSystemObject == false)
 urns.Add(t.Urn);
  DependencyTree dTree = dw.DiscoverDependencies(urns.ToArray(), true);
  DependencyCollection dColl = dw.WalkDependencies(dTree);

  foreach (var d in dColl)
  {
foreach (var s in schemaScripter.Script(new Urn[] { d.Urn }))
 strings.Add(s);
strings.Add("GO");
if (scriptData)
{
 int n = 0;
 foreach (var i in insertScripter.EnumScript(new Urn[] {d.Urn}))
 {
  strings.Add(i);
  if ((++n) % 100 == 0)
strings.Add("GO");
 }
}
  }
  ...
  File.WriteAllLines(path, strings);

经常添加"GO"以保持较小的批大小,这样SSMS就不会耗尽内存。

要完成该示例,数据库的脚本编写如下:

  foreach (var s in db.Script(new ScriptingOptions { ScriptSchema = true }))
strings.Add(s);
  strings.Add("GO");
  strings.Add("use " + dbName);
  strings.Add("GO");

用户、视图和存储过程的脚本编写如下:

  foreach (User u in db.Users)
  {
if (u.IsSystemObject == false)
{
 foreach (var s in u.Script(new ScriptingOptions { ScriptSchema = true }))
  strings.Add(s);
}
  }

此代码生成的文件可用于重新创建数据库。我在一台旧笔记本电脑上设置了它,以便每小时提取我的在线数据库的快照。可怜人的日志运输/备份/镜像。

好了关于无法获取EnumScript()以生成约束的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。