Mis indispensables de C#. Parte 2: Extensiones
Esta es una serie de 3 artículos cortos sobre características de C# que uso en todas mis aplicaciones.
Me gusta usar extension methods para validaciones. Aquí hay algunas básicas.
Es muy sencillo validar parámetros usando estas extensiones.
También las uso para interactuar con la base de datos, si por algún motivo no estoy usando un ORM.
Así es muy fácil manejar las columnas opcionales de un insert.
Y leer datos desde un SqlDataReader.
Extensiones… Muchas extensiones
Me gusta usar extension methods para validaciones. Aquí hay algunas básicas.
public static class ValueExtensions
{
public static string ThrowIfEmpty(this string value)
{
return string.IsNullOrWhiteSpace(value) ?
throw new ArgumentNullException() :
value.Trim();
}
public static string TrimOrThrow(this string value)
{
return value?.Trim() ??
throw new ArgumentNullException();
}
public static Guid ThrowIfEmpty(this Guid value)
{
return value == Guid.Empty ?
throw new ArgumentNullException() :
value;
}
public static DateTime ThrowIfInPast(this DateTime value)
{
return value <= DateTime.Now ?
throw new ArgumentOutOfRangeException() :
value;
}
public static DateTime NowIfDefault(this DateTime value)
{
return value == default(DateTime) ?
DateTime.Now :
value;
}
}
Es muy sencillo validar parámetros usando estas extensiones.
public async Task<TransferObject> DoSomething(
string userId,
Guid roleId,
string name,
DateTime meetingDate,
DateTime date)
{
userId.ThrowIfEmpty();
roleId.ThrowIfEmpty();
name = name.TrimOrThrow();
meetingDate.ThrowIfInPast();
date = date.NowIfDefault();
return await _store.SaveSomething(userId, roleId, name, meetingDate, date);
}
También las uso para interactuar con la base de datos, si por algún motivo no estoy usando un ORM.
public static class SqlExtensions
{
public static string GetStringOrNull(this SqlDataReader reader, int index)
{
return reader.IsDBNull(index) ?
null :
reader.GetString(index);
}
public static DateTime GetDateTimeOrNow(this SqlDataReader reader, int index)
{
return reader.IsDBNull(index) ?
DateTime.Now :
reader.GetDateTime(index);
}
public static DateTime? GetDateTimeOrNull(this SqlDataReader reader, int index)
{
return reader.IsDBNull(index) ?
null :
reader.GetDateTime(index);
}
public static Guid GetGuidOrEmpty(this SqlDataReader reader, int index)
{
return reader.IsDBNull(index) ?
Guid.Empty :
reader.GetGuid(index);
}
public static Guid? GetGuidOrNull(this SqlDataReader reader, int index)
{
return reader.IsDBNull(index) ?
null :
reader.GetGuid(index);
}
public static void SetSqlDBNullParameters(this SqlCommand command)
{
foreach (IDataParameter param in command.Parameters)
{
if (param.Value == null)
{
param.Value = DBNull.Value;
}
}
}
}
Así es muy fácil manejar las columnas opcionales de un insert.
string itemKey = "blog.lvbernal.com";
string itemValue = null;
string nonQuery = @"
INSERT INTO [some].[table] ([key], [value])
VALUES (@key, @value)";
using SqlConnection conn = new SqlConnection(_connectionString);
conn.Open();
using SqlCommand cmd = new SqlCommand(nonQuery, conn);
cmd.Parameters.AddWithValue("@key", itemKey);
cmd.Parameters.AddWithValue("@value", itemValue); // Esto genera un error
cmd.SetSqlDBNullParameters(); // Aquí reemplazamos los null por DBNull.Value
Y leer datos desde un SqlDataReader.
using SqlDataReader reader = await cmd.ExecuteReaderAsync();
if (reader.HasRows)
{
while (reader.Read())
{
var item = new ItemDTO(
id: reader.GetGuid(0),
name: reader.GetStringOrNull(1),
owner: reader.GetGuidOrNull(2)
);
list.Add(item);
}
}
Comentarios
Publicar un comentario