Ich arbeite an einer Anwendung, die Daten in zwei separate, aber verknüpfte Tabellen einfügt, wenn ein Benutzer eine Übergabeschaltfläche drückt.ADO.NET DataAdapters - Sicherstellen, dass eine Tabelle ein Update vor einem anderen ist
Da ich jedoch eine Fremdschlüsseleinschränkung auf einem Tisch habe, stößt ich auf Schwierigkeiten. Ich brauche die Zeilen für eine Tabelle (report_summary) wegen der Fremdschlüsseleinschränkungen zuerst eingefügt werden, bevor sogar eine einzelne Zeile zu der anderen Tabelle hinzugefügt wird (report_details). Allerdings möchte ich auch, dass sie in einer einzigen Transaktion behandelt werden, da einige Datenintegritätsprobleme bei einem Insert erfolgreich sein und bei dem anderen fehlschlagen. Wie kann ich das beheben?
Die T-SQL
CREATE TABLE [dbo].[report_summary] (
[report_id] INT NOT NULL,
[inspector] INT NOT NULL,
[employee] INT NOT NULL,
[room] INT NOT NULL,
[date] DATE NOT NULL,
[score] INT NOT NULL,
[locationID] INT NOT NULL,
PRIMARY KEY CLUSTERED ([report_id] ASC),
CONSTRAINT [FK_report_summary_locations] FOREIGN KEY ([locationID]) REFERENCES [dbo].[locations] ([locID])
);
CREATE TABLE [dbo].[report_details] (
[reportID] INT NOT NULL,
[itemID] INT NOT NULL,
[points] INT NOT NULL,
[comments] NTEXT NULL,
PRIMARY KEY CLUSTERED ([itemID] ASC, [reportID] ASC),
CONSTRAINT [FK_details_items] FOREIGN KEY ([itemID]) REFERENCES [dbo].[items] ([itemID]),
CONSTRAINT [FK_details_report] FOREIGN KEY ([reportID]) REFERENCES [dbo].[report_summary] ([report_id])
);
und einige meiner C#
private void submitData(object sender, RoutedEventArgs e)
{
SqlTransaction tran = con.BeginTransaction();
reportAdapter.InsertCommand.Transaction = tran;
SqlCommand query = new SqlCommand("SELECT report_id FROM dbo.report_summary ORDER by report_id DESC", con);
query.Transaction = tran;
int nextReportID;
if (query.ExecuteScalar() != null)
{
nextReportID = (int)query.ExecuteScalar() + 1;
}
else
{
nextReportID = 1;
}
detailsAdapter.InsertCommand.Transaction = tran;
DataRow reportRow = ds.Tables["Reports"].NewRow();
reportRow["report_id"] = nextReportID;
DataRowView inspectorSelection = (DataRowView)inspectorBox.SelectedItem;
reportRow["inspector"] = Int16.Parse(inspectorSelection["empID"].ToString());
DataRowView empSelection = (DataRowView)employeeBox.SelectedItem;
reportRow["employee"] = Int16.Parse(inspectorSelection["empID"].ToString());
DataRowView locationSelection = (DataRowView)locationComboBox.SelectedItem;
reportRow["locationID"] = Int16.Parse(locationSelection["locID"].ToString());
reportRow["room"] = Int16.Parse(roomTextBox.Text);
reportRow["date"] = DateTime.Now.ToString("yyy-MM-dd");
reportRow["score"] = currentPoints;
ds.Tables["Reports"].Rows.Add(reportRow);
// update report_details dataset
foreach (DataRow row in ds.Tables["Grid"].Rows)
{
DataRow reportDetailsRow = ds.Tables["Details"].NewRow();
reportDetailsRow["reportID"] = nextReportID;
reportDetailsRow["itemID"] = row["ID"];
reportDetailsRow["points"] = row["Current"];
reportDetailsRow["comments"] = row["Comments"];
ds.Tables["Details"].Rows.Add(reportDetailsRow);
}
// update tables as single transaction
try
{
reportAdapter.Update(ds, "Reports");
detailsAdapter.Update(ds, "Details");
tran.Commit();
MessageBox.Show("Data Inserted");
}
catch (SqlException sqlEr)
{
MessageBox.Show(sqlEr.Message);
tran.Rollback();
}
}
ich diesen Artikel von Microsoft verwiesen (https://msdn.microsoft.com/en-us/library/33y2221y(v=vs.110).aspx), aber aus meinem Verständnis angelegte Bestell Abschnitt wirklich, wenn es eine Tabelle, die Updates benötigt.
Danke!
Sind die Beziehungen für diese beiden Datentabellen im Dataset korrekt eingerichtet? –