我正在尝试使用代码将数据集导出为XML。
这就是我目前使用的:
dataSet.WriteXml(fileDialog.FileName, XmlWriteMode.WriteSchema);
我的dataSet是一个正确形成的类型化数据集(我的意思是,所有表都有PK,并且在dataSet中的所有现有表之间设置FK关系)。一些关系是嵌套关系。表“TABLE”有两个FK,同时是其他8个表的父级。
我收到以下错误:“无法继续序列化DataTable'TABLE'。它包含一个DataRow,它在同一个外键上有多个父行。”
Cna有人给我一些关于我做错的指示吗?为什么我收到此错误消息?
提前致谢。
答案 0 :(得分:2)
我知道它有点晚了,但我找到了解决方法。
我在尝试将架构读入具有关系的数据集时遇到了同样的问题。在这种情况下你会得到的错误是: '同一张表' {0}'不能是两个嵌套关系中的子表' 我将分享我所学到的知识
数据集以两种模式运行,但您无法从外部说明这一点。
您创建的数据集目前是' a'我们希望将其设为' b'。 它运行的模式是在DatSet被加载时决定的。 (xml)和/或其他一些注意事项。
我花了很多时间阅读DataSet的代码以找出欺骗它的方法,我发现MS可以通过在数据集上添加属性和一些额外的检查来解决问题。检查DataRelation的源代码:http://referencesource.microsoft.com/#System.Data/System/Data/DataRelation.cs,d2d504fafd36cd26,references并且我们需要愚弄的唯一方法是“ValidateMultipleNestedRelations”'方法。)
诀窍是欺骗数据集,使其认为自己构建所有关系。我发现这样做的唯一方法是通过使用序列化来实际创建数据集。
(我们在我们系统的一部分中使用此解决方案,我们使用面向DataSet的第三方产品创建输出。)
在meta中,您想要做的是:
一些实验告诉我,在这种情况下,少即是多。 如果DataSet读取架构,并找到NO关系或Key-Columns,它将以模式&b;#b;否则它将在模式' a'中工作。 我们仍然可以获得一个' b'具有SOME关系或Key-Columns的模式数据集,但这与我们的问题无关。
所以,我们开始,这段代码假设你有一个扩展方法'序列化'知道如何处理数据集。
假设sourceDataSet是仅包含模式的DataSet。 目标将是实际可用的数据集:
var sourceDataSet = new DataSet();
var source = sourceDataSet.Serialize();
// todo: create the structure of your dataset.
var endTagKeyColumn = " msdata:AutoIncrement=\"true\" type=\"xs:int\" msdata:AllowDBNull=\"false\" use=\"prohibited\" /";
var endTagKeyColumnLength = endTagKeyColumn.Length - 1;
var startTagConstraint = "<xs:unique ";
var endTagConstraint = "</xs:unique>";
var endTagConstraintLength = endTagConstraint.Length - 1;
var cleanedUp = new StringBuilder();
var subStringStart = 0;
var subStringEnd = source.IndexOf(endTagKeyColumn);
while (subStringEnd > 0)
{
// throw away unused key columns.
while (source[subStringEnd] != '<') subStringEnd--;
if (subStringEnd - subStringStart > 5)
{
cleanedUp.Append(source.Substring(subStringStart, subStringEnd - subStringStart));
}
subStringStart = source.IndexOf('>', subStringEnd + endTagKeyColumnLength) + 1;
subStringEnd = source.IndexOf(endTagKeyColumn, subStringStart);
}
subStringEnd = source.IndexOf(startTagConstraint, subStringStart);
while (subStringEnd > 0)
{
// throw away relationships.
if (subStringEnd - subStringStart > 5)
{
cleanedUp.Append(source.Substring(subStringStart, subStringEnd - subStringStart));
}
subStringStart = source.IndexOf(endTagConstraint, subStringEnd) + endTagConstraintLength;
subStringEnd = source.IndexOf(startTagConstraint, subStringStart);
}
cleanedUp.Append(source.Substring(subStringStart + 1));
target = new DataSet();
using (var reader = new StringReader(cleanedUp.ToString()))
{
target.EnforceConstraints = false;
target.ReadXml(reader, XmlReadMode.Auto);
}
注意,正如我在开始时所说的那样,我在加载数据集时必须解决这个问题,虽然您要保存数据集,但解决方法也是一样的。
答案 1 :(得分:1)
这两个外键导致了这个问题。键的另一端被认为是父母,所以你有两个。在编写XML时,元素只能有一个父元素(除非元素出现两次,每个父元素下面一次)。可能的解决方案包括删除其中一个外键(我很欣赏可能会以其他方式破坏您的应用),或者,根据dataSet
的初始化方式,尝试将EnforceConstraints
设置为false
。