-
Notifications
You must be signed in to change notification settings - Fork 0
System.Data.SqlClient
Benn Benson edited this page Jan 14, 2019
·
1 revision
For SQL Server, only null translation is necessary but unwrapping can be added if you want to use the methods and properties that return Sql* types.
For SQL Server Compact, change SqlCommand to SqlCeCommand and SqlParameter to SqlCeParameter.
public static class SqlClientExtensions
{
private static readonly ValueExtractor _extractor = ValueExtractor.Create(config =>
{
config.UseNullTester(obj => obj is DBNull);
// Configure unwrapping of the Sql* types that implement INullable.
config.UseUnwrapper(
// Test for System.Data.SqlTypes.INullable.
obj => obj is INullable,
// The Sql* types all have a public 'Value' property, but it's defined by each type
// rather than by a common base class or interface. Use a little reflection to get it.
// This could be optimized, of course.
obj => ((INullable)obj).IsNull ? null : obj.GetType().GetProperty("Value").GetValue(obj));
});
public static T Column<T>(this SqlDataReader reader, int i)
{
if (reader is null)
throw new ArgumentNullException(nameof(reader));
return _valueExtractor.Extract<T>(reader.GetValue(i));
}
public static T Column<T>(this SqlDataReader reader, string name)
{
if (reader is null)
throw new ArgumentNullException(nameof(reader));
return _valueExtractor.Extract<T>(reader.GetValue(reader.GetOrdinal(name)));
}
public static T GetValue<T>(this SqlParameter parameter)
{
if (parameter is null)
throw new ArgumentNullException(nameof(parameter));
return _valueExtractor.Extract<T>(parameter.Value);
}
// These extension methods retrieve the Sql* types. This is a rare use case so they
// can be omitted along with the UseUnwrapper call in the configuration above.
public static T SqlColumn<T>(this SqlDataReader reader, int i)
{
if (reader is null)
throw new ArgumentNullException(nameof(reader));
return _valueExtractor.Extract<T>(reader.GetSqlValue(i));
}
public static T SqlColumn<T>(this SqlDataReader reader, string name)
{
if (reader is null)
throw new ArgumentNullException(nameof(reader));
return _valueExtractor.Extract<T>(reader.GetSqlValue(reader.GetOrdinal(name)));
}
public static T GetSqlValue<T>(this SqlParameter parameter)
{
if (parameter is null)
throw new ArgumentNullException(nameof(parameter));
return _valueExtractor.Extract<T>(parameter.SqlValue);
}
}Call the Column extension method on the data reader and specify the BCL data type that corresponds to the type of the column.
int id = reader.Column<int>("ID");
string name = reader.Column<string>("Name");