如果我执行类似下面的操作,然后添加一个外键值不是主表中的主键值的行,则不会引发错误。我想做的是以下几点:
1)建立一些对外关系。 2)将一些数据合并到数据集中,但不合并违反外来关系的行。 3)将错误的行写入逗号分隔文件,excel文件,DataSet或其他内容。
DataColumn pkColumn =
AllData.Tables["ParentTable"].Columns["PrimaryKeyColumn"];
DataColumn fkColumn =
AllData.Tables["ChildTable"].Columns["ForeignKeyColumn"];
DataRelation testRelations =
new DataRelation("RelationName", pkColumn, fkColumn);
AllData.Relations.Add(testRelations);
我该怎么做?即使我必须逐行插入DataSet,只要我没有进行一些硬编码检查,那也没关系。
亲切的问候, 河豚
答案 0 :(得分:0)
如果执行单次插入,则可以在插入时检查不良亲属。您可以将错误数据复制到新表中。
在这个例子中,我定义了一个名为“dsBadRowTest”的类型化数据集,其中包含一个名为“ParentTable”的表,其中包含“PrimaryKeyColumn”列。它是“ForeignKeyColumn”上另一个名为“ChildTable”的表的父表。我定义了一个关系数据集,然后尝试添加无效的子项。对于每个无效的子项,我将列信息存储在单独的表变量中。
//Our relational dataset...
dsBadRowTest dsRelated = new dsBadRowTest();
//The error table will be a non-relational version
dsBadRowTest.ChildTableDataTable dtErrors = new dsBadRowTest.ChildTableDataTable();
//Add an extra column the error table for extra info
dtErrors.Columns.Add("ErrorMessage");
//Fill our parent table
for (Int32 i = 1; i <= 5; i++) {
dsRelated.ParentTable.AddParentTableRow(i);
}
//attempt to fill our child table, with invalid children
for (Int32 i = 1; i <= 10; i++) {
dsBadRowTest.ChildTableRow drNewChild = dsRelated.ChildTable.NewChildTableRow;
drNewChild.ForeignKeyColumn = i;
try {
dsRelated.ChildTable.AddChildTableRow(drNewChild);
} catch (Data.InvalidConstraintException ex) {
//Problem adding...Copy the row for the error table
dsBadRowTest.ChildTableRow drError = dtErrors.NewChildTableRow;
foreach (System.Data.DataColumn dc in drNewChild.Table.Columns) {
drError(dc.ColumnName) = drNewChild(dc);
}
//Our non-typed extra column will contain the error message
drError("ErrorMessage") = ex.Message;
dtErrors.AddChildTableRow(drError);
}
}
if (dtErrors.Rows.Count > 0) {
//Uh oh, we had some bad inserts
//...do something with the list of errors...
}
您可以保持关系到位,并检查特定的例外情况。
(这是我用于此示例的类型化数据集...(dsBadRowTest.xsd)
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="dsBadRowTest" targetNamespace="http://tempuri.org/dsBadRowTest.xsd" xmlns:mstns="http://tempuri.org/dsBadRowTest.xsd" xmlns="http://tempuri.org/dsBadRowTest.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop" attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:annotation>
<xs:appinfo source="urn:schemas-microsoft-com:xml-msdatasource">
<DataSource DefaultConnectionIndex="0" FunctionsComponentName="QueriesTableAdapter" Modifier="AutoLayout, AnsiClass, Class, Public" SchemaSerializationMode="IncludeSchema" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<Connections />
<Tables />
<Sources />
</DataSource>
</xs:appinfo>
</xs:annotation>
<xs:element name="dsBadRowTest" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msprop:Generator_DataSetName="dsBadRowTest" msprop:Generator_UserDSName="dsBadRowTest">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="ParentTable" msprop:Generator_TableClassName="ParentTableDataTable" msprop:Generator_TableVarName="tableParentTable" msprop:Generator_TablePropName="ParentTable" msprop:Generator_RowDeletingName="ParentTableRowDeleting" msprop:Generator_UserTableName="ParentTable" msprop:Generator_RowChangingName="ParentTableRowChanging" msprop:Generator_RowEvHandlerName="ParentTableRowChangeEventHandler" msprop:Generator_RowDeletedName="ParentTableRowDeleted" msprop:Generator_RowEvArgName="ParentTableRowChangeEvent" msprop:Generator_RowChangedName="ParentTableRowChanged" msprop:Generator_RowClassName="ParentTableRow">
<xs:complexType>
<xs:sequence>
<xs:element name="PrimaryKeyColumn" msprop:Generator_ColumnVarNameInTable="columnPrimaryKeyColumn" msprop:Generator_ColumnPropNameInRow="PrimaryKeyColumn" msprop:Generator_ColumnPropNameInTable="PrimaryKeyColumnColumn" msprop:Generator_UserColumnName="PrimaryKeyColumn" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ChildTable" msprop:Generator_TableClassName="ChildTableDataTable" msprop:Generator_TableVarName="tableChildTable" msprop:Generator_TablePropName="ChildTable" msprop:Generator_RowDeletingName="ChildTableRowDeleting" msprop:Generator_UserTableName="ChildTable" msprop:Generator_RowChangingName="ChildTableRowChanging" msprop:Generator_RowEvHandlerName="ChildTableRowChangeEventHandler" msprop:Generator_RowDeletedName="ChildTableRowDeleted" msprop:Generator_RowEvArgName="ChildTableRowChangeEvent" msprop:Generator_RowChangedName="ChildTableRowChanged" msprop:Generator_RowClassName="ChildTableRow">
<xs:complexType>
<xs:sequence>
<xs:element name="ForeignKeyColumn" msprop:Generator_ColumnVarNameInTable="columnForeignKeyColumn" msprop:Generator_ColumnPropNameInRow="ForeignKeyColumn" msprop:Generator_ColumnPropNameInTable="ForeignKeyColumnColumn" msprop:Generator_UserColumnName="ForeignKeyColumn" type="xs:int" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//mstns:ParentTable" />
<xs:field xpath="mstns:PrimaryKeyColumn" />
</xs:unique>
<xs:keyref name="FK_ParentTable_ChildTable" refer="Constraint1" msprop:rel_Generator_UserChildTable="ChildTable" msprop:rel_Generator_ChildPropName="GetChildTableRows" msprop:rel_Generator_UserParentTable="ParentTable" msprop:rel_Generator_UserRelationName="FK_ParentTable_ChildTable" msprop:rel_Generator_RelationVarName="relationFK_ParentTable_ChildTable" msprop:rel_Generator_ParentPropName="ParentTableRow" msdata:UpdateRule="None" msdata:DeleteRule="None">
<xs:selector xpath=".//mstns:ChildTable" />
<xs:field xpath="mstns:ForeignKeyColumn" />
</xs:keyref>
</xs:element>
</xs:schema>
我希望这会对你有所帮助。