using System.Data.Common;
namespace System.Data.SqlClient;
public delegate void SqlRowUpdatingEventHandler(object sender, SqlRowUpdatingEventArgs e);
public delegate void SqlRowUpdatedEventHandler(object sender, SqlRowUpdatedEventArgs e);
public sealed class SqlRowUpdatingEventArgs : RowUpdatingEventArgs
{
public SqlRowUpdatingEventArgs(DataRow row, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping)
: base(row, command, statementType, tableMapping) { }
public new SqlCommand? Command
{
get => (SqlCommand?)base.Command;
set => base.Command = value;
}
}
public sealed class SqlRowUpdatedEventArgs : RowUpdatedEventArgs
{
public SqlRowUpdatedEventArgs(DataRow row, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping)
: base(row, command, statementType, tableMapping) { }
public new SqlCommand? Command => (SqlCommand?)base.Command;
}
/// 在数据库和 DataSet 之间搬运数据:Fill 读出来,Update 把 DataTable 里改过的行写回去
public sealed class SqlDataAdapter : DbDataAdapter, ICloneable
{
public SqlDataAdapter() { }
public SqlDataAdapter(SqlCommand selectCommand) => SelectCommand = selectCommand;
public SqlDataAdapter(string selectCommandText, SqlConnection selectConnection) => SelectCommand = new SqlCommand(selectCommandText, selectConnection);
public SqlDataAdapter(string selectCommandText, string selectConnectionString) =>
SelectCommand = new SqlCommand(selectCommandText, new SqlConnection(selectConnectionString));
public new SqlCommand? SelectCommand
{
get => (SqlCommand?)base.SelectCommand;
set => base.SelectCommand = value;
}
public new SqlCommand? InsertCommand
{
get => (SqlCommand?)base.InsertCommand;
set => base.InsertCommand = value;
}
public new SqlCommand? UpdateCommand
{
get => (SqlCommand?)base.UpdateCommand;
set => base.UpdateCommand = value;
}
public new SqlCommand? DeleteCommand
{
get => (SqlCommand?)base.DeleteCommand;
set => base.DeleteCommand = value;
}
public event SqlRowUpdatingEventHandler? RowUpdating;
public event SqlRowUpdatedEventHandler? RowUpdated;
protected override RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) =>
new SqlRowUpdatingEventArgs(dataRow, command, statementType, tableMapping);
protected override RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand? command, StatementType statementType, DataTableMapping tableMapping) =>
new SqlRowUpdatedEventArgs(dataRow, command, statementType, tableMapping);
protected override void OnRowUpdating(RowUpdatingEventArgs value) => RowUpdating?.Invoke(this, (SqlRowUpdatingEventArgs)value);
protected override void OnRowUpdated(RowUpdatedEventArgs value) => RowUpdated?.Invoke(this, (SqlRowUpdatedEventArgs)value);
object ICloneable.Clone() => new SqlDataAdapter { SelectCommand = SelectCommand, InsertCommand = InsertCommand, UpdateCommand = UpdateCommand, DeleteCommand = DeleteCommand };
}
/// 按 SqlDataAdapter 的查询语句自动生成 INSERT / UPDATE / DELETE(要求查询包含主键列)
public sealed class SqlCommandBuilder : DbCommandBuilder
{
public SqlCommandBuilder()
{
QuotePrefix = "[";
QuoteSuffix = "]";
}
public SqlCommandBuilder(SqlDataAdapter adapter) : this() => DataAdapter = adapter;
public new SqlDataAdapter? DataAdapter
{
get => (SqlDataAdapter?)base.DataAdapter;
set => base.DataAdapter = value;
}
public new SqlCommand GetInsertCommand() => (SqlCommand)base.GetInsertCommand();
public new SqlCommand GetInsertCommand(bool useColumnsForParameterNames) => (SqlCommand)base.GetInsertCommand(useColumnsForParameterNames);
public new SqlCommand GetUpdateCommand() => (SqlCommand)base.GetUpdateCommand();
public new SqlCommand GetUpdateCommand(bool useColumnsForParameterNames) => (SqlCommand)base.GetUpdateCommand(useColumnsForParameterNames);
public new SqlCommand GetDeleteCommand() => (SqlCommand)base.GetDeleteCommand();
public new SqlCommand GetDeleteCommand(bool useColumnsForParameterNames) => (SqlCommand)base.GetDeleteCommand(useColumnsForParameterNames);
protected override void ApplyParameterInfo(DbParameter parameter, DataRow row, StatementType statementType, bool whereClause) { }
protected override string GetParameterName(int parameterOrdinal) => "@p" + parameterOrdinal.ToString(Globalization.CultureInfo.InvariantCulture);
protected override string GetParameterName(string parameterName) => "@" + parameterName;
protected override string GetParameterPlaceholder(int parameterOrdinal) => GetParameterName(parameterOrdinal);
public override string QuoteIdentifier(string unquotedIdentifier) => "[" + unquotedIdentifier.Replace("]", "]]") + "]";
protected override void SetRowUpdatingHandler(DbDataAdapter adapter)
{
if (adapter is not SqlDataAdapter sql) throw new InvalidOperationException("SqlCommandBuilder 只能用于 SqlDataAdapter。");
if (adapter == base.DataAdapter) sql.RowUpdating += Handler;
else sql.RowUpdating -= Handler;
}
private void Handler(object sender, SqlRowUpdatingEventArgs e) => RowUpdatingHandler(e);
}