Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Dotyczy:programu SQL Server
Typy zdefiniowane przez użytkownika (UDT) można pobierać i modyfikować przy użyciu obiektu System.Data.DataSet i Microsoft.Data.SqlClient.SqlDataAdapter.
Przykłady kodu w tym artykule używają elementu Microsoft.Data.SqlClient, który jest dostępny jako pakiet NuGet. Aby dodać tę zależność do projektu, uruchom następujące polecenie:
dotnet add package Microsoft.Data.SqlClient
Wypełnianie zestawu danych
Użyj instrukcji SELECT Transact-SQL, aby wybrać wartości kolumn UDT w celu wypełnienia zestawu danych przy użyciu karty danych. W poniższym przykładzie przyjęto założenie, że masz tabelę Points zdefiniowaną z następującą strukturą i przykładowymi danymi. Poniższe instrukcje Transact-SQL tworzą tabelę Points i wstawią kilka wierszy.
CREATE TABLE dbo.Points
(
id INT PRIMARY KEY,
p Point
);
INSERT INTO dbo.Points
VALUES (1, CONVERT (Point, '1,3'));
INSERT INTO dbo.Points
VALUES (2, CONVERT (Point, '2,4'));
INSERT INTO dbo.Points
VALUES (3, CONVERT (Point, '3,5'));
INSERT INTO dbo.Points
VALUES (4, CONVERT (Point, '4,6'));
GO
Poniższy fragment kodu ADO.NET pobiera prawidłowe parametry połączenia, tworzy nowe SqlDataAdapteri wypełnia System.Data.DataTable wierszami danych z tabeli Points.
SqlDataAdapter da = new SqlDataAdapter(
"SELECT id, p FROM dbo.Points", connectionString);
DataTable datTable = new DataTable("Points");
da.Fill(datTable);
Aktualizowanie danych UDT w zestawie danych
Za pomocą dwóch metod można zaktualizować kolumnę UDT w DataSet:
Podaj niestandardowe obiekty
InsertCommand,UpdateCommandiDeleteCommanddla obiektuSqlDataAdapter.Użyj konstruktora poleceń (
Microsoft.Data.SqlClient.SqlCommandBuilder), aby automatycznie utworzyć poleceniaINSERT,UPDATEiDELETE. Aby włączyć wykrywanie konfliktów, dodaj kolumnę sygnatury czasowej (alias rowversion) do tabeli programu SQL Server, która zawiera funkcję UDT. Sygnatura czasowa typ danych umożliwia oznaczenie wersji wierszy w tabeli i gwarantuje unikatowość w bazie danych. Po zmianie wartości w tabeli program SQL Server automatycznie aktualizuje 8-bajtowy numer binarny dla wiersza, którego dotyczy zmiana.
SqlCommandBuilder nie uwzględnia funkcji UDT do wykrywania konfliktów, chyba że w tabeli bazowej znajduje się sygnatura czasowa. Trasy zdefiniowane przez użytkownika mogą być porównywalne, dlatego nie są uwzględniane w klauzuli WHERE, gdy opcja "porównaj oryginalne wartości" jest używana do generowania polecenia.
Przykład
Poniższy przykład wymaga utworzenia drugiej tabeli zawierającej kolumnę udT Point i sygnaturę czasową. Obie tabele służą do zilustrowania sposobu tworzenia niestandardowych obiektów poleceń w celu aktualizowania danych oraz sposobu aktualizowania przy użyciu sygnatury czasowej kolumny. Uruchom następujące instrukcje Transact-SQL, aby utworzyć drugą tabelę i wypełnić ją przykładowymi danymi.
CREATE TABLE dbo.Points_ts
(
id INT PRIMARY KEY,
p Point,
ts TIMESTAMP
);
INSERT INTO dbo.Points_ts (id, p)
VALUES (1, CONVERT (Point, '1,3'));
INSERT INTO dbo.Points_ts (id, p)
VALUES (2, CONVERT (Point, '2,4'));
INSERT INTO dbo.Points_ts (id, p)
VALUES (3, CONVERT (Point, '3,5'));
INSERT INTO dbo.Points_ts (id, p)
VALUES (4, CONVERT (Point, '4,6'));
Poniższy przykład ADO.NET ma dwie metody:
UserProvidedCommands, który demonstruje sposób podawaniaInsertCommandobiektów ,UpdateCommandiDeleteCommanddo aktualizowaniaPointudT wPointstabeli (bez kolumny znacznika czasu ).CommandBuilder, który pokazuje, jak używaćSqlCommandBuilderw tabeliPoints_tszawierającej sygnaturę czasową kolumny.
using System;
using System.Data;
using Microsoft.Data.SqlClient;
class Class1
{
// Retrieves the connection string
private string connString = GetConnectionString();
static void Main()
{
UserProvidedCommands();
CommandBuilder();
}
static void UserProvidedCommands()
{
// Create a new SqlDataAdapter
SqlDataAdapter da = new SqlDataAdapter(
"SELECT id, p FROM dbo.Points", connString);
// Setup the INSERT/UPDATE/DELETE commands
SqlParameter idParam;
SqlParameter pointParam;
da.InsertCommand = new SqlCommand(
"INSERT INTO dbo.Points (id, p) VALUES (@id, @p)",
da.SelectCommand.Connection);
idParam =
da.InsertCommand.Parameters.Add("@id", SqlDbType.Int);
idParam.SourceColumn = "id";
pointParam =
da.InsertCommand.Parameters.Add("@p", SqlDbType.Udt);
pointParam.SourceColumn = "p";
pointParam.UdtTypeName = "dbo.Point";
da.UpdateCommand = new SqlCommand(
"UPDATE dbo.Points SET p = @p WHERE id = @id",
da.SelectCommand.Connection);
idParam =
da.UpdateCommand.Parameters.Add("@id", SqlDbType.Int);
idParam.SourceColumn = "id";
pointParam =
da.UpdateCommand.Parameters.Add("@p", SqlDbType.Udt);
pointParam.SourceColumn = "p";
pointParam.UdtTypeName = "dbo.Point";
da.DeleteCommand = new SqlCommand(
"DELETE dbo.Points WHERE id = @id",
da.SelectCommand.Connection);
idParam =
da.DeleteCommand.Parameters.Add("@id", SqlDbType.Int);
idParam.SourceColumn = "id";
// Fill the DataTable with UDT rows
DataTable datTable = new DataTable("Points");
da.Fill(datTable);
// Display the contents of the p (Point) column
foreach (DataRow r in datTable.Rows)
{
Point p = (Point)r[1];
Console.WriteLine(
"ID: {0}, x={1}, y={1}", r[0], p.X, p.Y);
}
// Update a row if the DataTable has at least 1 row
if (datTable.Rows.Count > 0)
{
Point oldPoint = (Point)datTable.Rows[0][1];
datTable.Rows[0][1] =
new Point(oldPoint.X + 1, oldPoint.Y + 1);
}
// Delete the last row
if (datTable.Rows.Count > 0)
{
// If we have at least 1 row
datTable.Rows[1].Delete();
}
// Insert a row. This will fail if run twice
// because 100 is a primary key value.
datTable.Rows.Add(100, new Point(100, 200));
// Send the changes back to the database
da.Update(datTable);
}
static void CommandBuilder()
{
// Create a new SqlDataAdapter
SqlDataAdapter da = new SqlDataAdapter(
"SELECT id, ts, p FROM dbo.Points_ts", connString);
// Select a few rows with UDTs from the database
DataTable datTable = new DataTable("Points");
da.Fill(datTable);
// Display the contents of the p (Point) column
foreach (DataRow r in datTable.Rows)
{
Point p = (Point)r[2];
Console.WriteLine(
"ID: {0}, x={1}, y={1}", r[0], p.X, p.Y);
}
// Update a row if DataTable has at least 1 row
if (datTable.Rows.Count > 0)
{
Point oldPoint = (Point)datTable.Rows[0][2];
datTable.Rows[0][2] =
new Point(oldPoint.X + 1, oldPoint.Y + 1);
}
// Delete the last row
if (datTable.Rows.Count > 0)
{
// if we have at least 1 row
datTable.Rows[1].Delete();
}
// Insert a row. This will fail if run twice
// because 100 is a primary key value
datTable.Rows.Add(100, null, new Point(100, 200));
// Use the CommandBuilder to generate DML statements
SqlCommandBuilder bld = new SqlCommandBuilder(da);
bld.ConflictDetection = ConflictOptions.CompareRowVersion;
// Send the changes back to the database
da.Update(datTable);
}
static private string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return "Data Source=localhost;Initial Catalog=AdventureWorks2022;"
+ "Integrated Security=SSPI";
}
}