DataSet表可以填充来自两个来源的数据吗?

时间:2016-04-29 09:54:02

标签: c# dataset

我有DataSet并从中读取两个来源的数据。来自XML文件的一个表和来自Firebird SQL数据库的另一个表。我试图得到的只有一个表包含XML文件中的所有列和单个表中SQL数据的一些字段。两个表都具有相同的唯一键字段,因此可以轻松合并。我想将此表的所有字段绑定到表单上的字段。

是否可能像描述的那样,或者我没有看到解决问题的方法更简单?

修改: 为了表明我尝试做了一些额外的代码。

DataSet dataSet = new DataSet();

DataTable table1 = new DataTable("test1", "test1");
table1.Columns.Add("id");
table1.Columns.Add("name");
table1.Columns[0].Unique = true;

table1.Rows.Add(new object[2] { 1, "name1" });
table1.Rows.Add(new object[2] { 2, "name2" });

DataTable table2 = new DataTable("test2", "test2");
table2.Columns.Add("id");
table2.Columns.Add("thing");
table2.Columns[0].Unique = true;

table2.Rows.Add(new object[2] { 1, "thing1" });
table2.Rows.Add(new object[2] { 2, "thing2" });

dataSet.Tables.Add(table1);
dataSet.Tables[0].Merge(table2, false);

当我运行此代码时,我得到ConstraintException。当我删除id字段中的唯一字符时,它会在列表中填入所有必需的列,但其中一行包含table1的数据,另一行包含table2个数据。我该如何合并?

编辑2 : 我尝试在实时数据中使用PrimaryKey解决方案。

xmlData.Tables[0].PrimaryKey = new[] { xmlData.Tables[0].Columns["usnr"] };
dbData.PrimaryKey = new[] { dbData.Columns["usid"] };
xmlData.Tables[0].Merge(dbData, true, MissingSchemaAction.Add);

xmlData是来自XML文件的DataSet。它有id,usnr和其他一些领域。 dbData是DataTable,其数据来自db,它具有id,usid,name和一些其他字段。 id字段与我的数据无关。 usnr和usid这两个字段都是表中的字符串,因为我使用GetType()进行了测试。

当我现在添加xmlData.Tables[0].Merge(dbData, true, MissingSchemaAction.Add);时,它会抛出DataException

<target>.ID and <source>.ID have conflicting properties: DataType property mismatch.

写这篇文章的时候,我意识到两个表中的id字段不同,但我不需要它们,所以在更改primaryKey条目和合并之前删除了列。现在我得到一个NullReferenceException,但没有更多信息。这些表都很好,并且有数据,现在Exception会出现在哪里?

3 个答案:

答案 0 :(得分:2)

而不是......

table1.Columns[0].Unique = true;
table2.Columns[0].Unique = true;

...添加以下行:

table1.PrimaryKey = new[] { table1.Columns[0] };
table2.PrimaryKey = new[] { table2.Columns[0] };

因为merge命令需要知道数据表的主键。仅指示哪些列是唯一的是不够的。使用主键输出将是:

id name  thing
== ===== ======
1  name1 thing1 
2  name2 thing2 

请注意,要使其正常工作,主键字段必须具有匹配的数据类型名称。如果数据类型不匹配,则会收到相应的错误消息。但是,如果名称不匹配,则抛出一个非描述性的空引用异常。微软本可以在那里做得更好。

这意味着在您的情况下,我建议在合并数据表之前重命名usnrusid

答案 1 :(得分:1)

您可以将Linq用于此目的并加入您的两个DataTables,如下所示:

.........
.........
dataSet.Tables.Add(table1);
//dataSet.Tables[0].Merge(table2, false);

var collection = from t1 in dataSet.Tables[0].AsEnumerable()
                 join t2 in table2.AsEnumerable()
                 on t1["id"] equals t2["id"]
                 select new
                 {
                     ID = t1["id"],
                     Name = t1["name"],
                     Thing = t2["thing"]
                 };

DataTable result = new DataTable("Result");
result.Columns.Add("ID", typeof(string));
result.Columns.Add("Name", typeof(string));
result.Columns.Add("Thing", typeof(string));

foreach (var item in collection)
{
    result.Rows.Add(item.ID, item.Name, item.Thing);
}

DataGridView中的结果将是您想要的结果,如下所示:

dataGridView1.DataSource = result;

enter image description here

答案 2 :(得分:0)

在这里,您无法将这两个数据表合并在一起。你需要在这两个表中合并迭代每个数据的数据。

创建包含所有列(Id,Name,Thing)的新数据表。然后填充那个表读另外两个。