数据集丢失并在 C# 中合并
最新编辑!!!
请...我已经对这段代码进行了多次排列。我正在尝试从数据库(SQL 服务器)中获取一些某些相关记录并导出到 XML(这似乎有效!),并将它们带到该数据库的断开连接副本,并将它们导入到该数据库,按主数据库合并它们键(如果键存在则更新,如果不存在则插入)。
数据库中有很多表,我想要与已更改的某个实体列表相关的所有表。我很早就发现我无法使用联接执行大型复杂查询来获取我想要填充导出数据集的所有列,因为我丢失了所有表结构。我还让 Visual Studio 2005 数据集设计器创建了一个类型化数据集,我不确定是否需要这样做,如果不需要,请告诉我。
下面是我将数据导出到 xml 的方法:
public void exportData(string filename, List sxOrgs) {
MyGeneratedDataSet ds = new MyGeneratedDataSet();
SqlDataAdapter adapter = new SqlDataAdapter();
String query;
String orgList = "(";
//create the string query list of sxOrgs
foreach (String sx in sxOrgs)
{
orgList += "'" + sx + "', ";
}
orgList = orgList.Remove(orgList.Length - 2);
orgList += ")";
try
{
//tblOrganization
query = "select * from tblOrganization where tblOrganization.sxOrganization in "
+ orgList;
adapter.SelectCommand = new SqlCommand(query, Connectivity.Connection());
adapter.Fill(ds.tblOrganization);
//tblCategory
query = "select * from tblCategory where sxCategory in " +
"(select sxCategory from lnkOrganizationCategory " +
"where lnkOrganizationCategory.sxOrganization in " +
orgList + ")";
adapter.SelectCommand = new SqlCommand(query, Connectivity.Connection());
adapter.Fill(ds.tblCategory);
//lnkOrganizationCategory
query = "select * from lnkOrganizationCategory where sxOrganization in " + orgList;
adapter.SelectCommand = new SqlCommand(query, Connectivity.Connection());
adapter.Fill(ds.lnkOrganizationCategory);
//tblContact
query = "select * from tblContact where sxContact in " +
"(select sxContact from lnkOrganizationContact " +
"where lnkOrganizationContact.sxOrganization in " +
orgList + ")";
adapter.SelectCommand = new SqlCommand(query, Connectivity.Connection());
adapter.Fill(ds.tblContact);
//lnkOrganizationContact
query = "select * from lnkOrganizationContact where lnkOrganizationContact.sxOrganization in " + orgList;
adapter.SelectCommand = new SqlCommand(query, Connectivity.Connection());
adapter.Fill(ds.lnkOrganizationContact);
} catch(Exception ex) {
Debug.WriteLine(ex.Message);
}
ds.WriteXml(filename, XmlWriteMode.IgnoreSchema);
}
如您所见,我一遍又一遍地重复使用同一个 TableAdapeter,最后编写的 XML 看起来很好,每个都有一个标签表,并在其中为每个字段添加一个标记,这正是我想要的,并且能够将其合并回来。这是导入代码:
//reads data from an xml file and merges it into existing db
public static void ImportData(string data)
{
try
{
MyGeneratedDataSet newData = new MyGeneratedDataSet();
StreamWriter sw = new StreamWriter("newdata.xml", false);
Debug.WriteLine(data);
sw.Write(data);
sw.Close();
XmlTextReader reader = new XmlTextReader(new MemoryStream(ASCIIEncoding.Default.GetBytes(data)));
newData.ReadXml("newData.xml");
MyGeneratedDataSet currentData = new MyGeneratedDataSet();
//tblOrganization
SqlDataAdapter tblOrganizationDataAdapter = new SqlDataAdapter("select * from tblOrganization", Connectivity.Connection());
SqlCommandBuilder tblOrganizationCommandBuilder = new SqlCommandBuilder(tblOrganizationDataAdapter);
tblOrganizationDataAdapter.Fill(currentData, "tblOrganization");
//tblContact
SqlDataAdapter tblContactDataAdapter = new SqlDataAdapter("select * from tblContact", Connectivity.Connection());
SqlCommandBuilder tblContactCommandBuilder = new SqlCommandBuilder(tblContactDataAdapter);
tblContactDataAdapter.Fill(currentData, "tblContact");
//tblCategory
SqlDataAdapter tblCategoryDataAdapter = new SqlDataAdapter("select * from tblCategory", Connectivity.Connection());
SqlCommandBuilder tblCategoryCommandBuilder = new SqlCommandBuilder(tblCategoryDataAdapter);
tblCategoryDataAdapter.Fill(currentData, "tblCategory");
//lnkOrganizationCategory
SqlDataAdapter lnkOrganizationCategoryDataAdapter = new SqlDataAdapter("select * from lnkOrganizationCategory", Connectivity.Connection());
SqlCommandBuilder lnkOrganizationCategoryCommandBuilder = new SqlCommandBuilder(lnkOrganizationCategoryDataAdapter);
lnkOrganizationCategoryDataAdapter.Fill(currentData, "lnkOrganizationCategory");
//lnkOrganizationContact
SqlDataAdapter lnkOrganizationContactDataAdapter = new SqlDataAdapter("select * from lnkOrganizationContact", Connectivity.Connection());
SqlCommandBuilder lnkOrganizationContactCommandBuilder = new SqlCommandBuilder(lnkOrganizationContactDataAdapter);
lnkOrganizationContactDataAdapter.Fill(currentData, "lnkOrganizationContact");
Debug.WriteLine(tblOrganizationDataAdapter.SelectCommand.CommandText);
Debug.WriteLine(tblOrganizationDataAdapter.UpdateCommand.CommandText);
currentData.Merge(newData);
tblOrganizationDataAdapter.Update(currentData);
tblContactDataAdapter.Update(currentData);
tblCategoryDataAdapter.Update(currentData);
lnkOrganizationCategoryDataAdapter.Update(currentData);
lnkOrganizationContactDataAdapter.Update(currentData);
} catch (Exception ex) {
Debug.WriteLine(ex.Message);
}
}
目前,导入函数末尾附近的 Debug.WriteLine 显示tblOrganizationTableAdapter 的 UpdateCommand 为空。视觉设计师告诉我,它创建它是为了,尽管如果我所要做的就是创建它,当然,我会这样做,但我现在已经重写了很多次(而且还有比这更多的表) ,我还是不明白发生了什么事。我应该怎么做?
太感谢了! Joshua
这段代码几乎可以工作。现在它不再失败了,但是,我最终得到了所有重复的行,而不是通过主键比较进行更新!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你正在做的事情听起来是对的。我不确定您的确切问题是什么,但这里是流程的细分:
当您执行步骤 #4 时,表适配器会查看
DataSet
中的每个表并找出哪些行已更改。它之所以知道,是因为每个DataTable
中的每个DataRow
都会将其DataRowState
设置为Added
、ModifiedMerge()
,导致或
)。当此过程完成时,底层数据库应该包含 NewData 数据集包含的所有更改。Deleted
。然后,表适配器在底层数据库中执行请求的更改,并将DataRow
的DataRowState
设置为Unchanged
(DataRow
的情况除外) >当然,已删除What you are doing sounds right. I'm not sure what your exact problem is, but here is a breakdown of the flow:
When you perform step #4, the table adapters look at each table in the
DataSet
and find out which rows have changed. It knows because eachDataRow
in eachDataTable
will have itsDataRowState
set toAdded
,Modified
orDeleted
as a result of your call toMerge()
. The table adapter then performs the requested change in the underlying database and sets theDataRowState
toUnchanged
for theDataRow
(except in the case ofDeleted
, of course). When this process completes, the underlying database should have all the changes in it that the NewData dataset contained.Blah:
代码:
Blah:
Code:
update 需要在某个时刻被调用:
一般来说,直接在 sql 中合并 2 个表可能更容易,但是您的应用程序可能需要处理 xml 文件..
使用合并/更新的示例:
http://msdn.microsoft.com/en-us/library/aa325628%28VS.71 %29.aspx
在 t-sql 中,您可以使用 MERGE 在一条语句中执行此操作:
http://technet.microsoft.com/en-us/library/bb510625.aspx
调整它以适应您想要更改/更新行时的条件
update would need to be called at some point:
in general its probably easier to merge 2 tables directly in sql, but your app may need to process xml files..
examples of using Merge/Update:
http://msdn.microsoft.com/en-us/library/aa325628%28VS.71%29.aspx
in t-sql, you can do this in one statement with MERGE:
http://technet.microsoft.com/en-us/library/bb510625.aspx
tweak it to suit the conditions when you want the row changed / updated