Así que estoy usando un IDataReader para hidratar algunos objetos comerciales, pero no sé en tiempo de ejecución qué campos exactamente estarán en el lector. Cualquier campo que no esté en el lector se dejará nulo en el objeto resultante. ¿Cómo se prueba si un lector contiene un campo específico sin simplemente envolverlo en un try/catch?Detectando si un IDataReader contiene un cierto campo antes de la iteración
Respuesta
No se puede simplemente probar el lector ["field"] para null o DBNull porque se lanza IndexOutOfRangeException si la columna no está en el lector.
El código que uso en mi capa de mapeo para crear objetos de dominio y los procedimientos almacenados que usan la capa de mapeo pueden tener diferentes nombres de columna; puedes modificarlo para que no genere una excepción si la columna no se encuentra y devuelve el valor predeterminado (t) o nulo.
Entiendo que esta no es la solución más elegante u óptima (y en realidad, si puede evitarla, entonces debería hacerlo), sin embargo, los procedimientos almacenados heredados o las consultas Sql pueden garantizar una solución alternativa.
/// <summary>
/// Grabs the value from a specific datareader for a list of column names.
/// </summary>
/// <typeparam name="T">Type of the value.</typeparam>
/// <param name="reader">Reader to grab data off of.</param>
/// <param name="columnNames">Column names that should be interrogated.</param>
/// <returns>Value from the first correct column name or an exception if none of the columns exist.</returns>
public static T GetColumnValue<T>(IDataReader reader, params string[] columnNames)
{
bool foundValue = false;
T value = default(T);
IndexOutOfRangeException lastException = null;
foreach (string columnName in columnNames)
{
try
{
int ordinal = reader.GetOrdinal(columnName);
value = (T)reader.GetValue(ordinal);
foundValue = true;
}
catch (IndexOutOfRangeException ex)
{
lastException = ex;
}
}
if (!foundValue)
{
string message = string.Format("Column(s) {0} could not be not found.",
string.Join(", ", columnNames));
throw new IndexOutOfRangeException(message, lastException);
}
return value;
}
Si bien estoy de acuerdo con este enfoque (creo que al acceder a datos, usted debe saber la forma antes de la mano), entiendo que hay excepciones.
Siempre se puede cargar una tabla de datos con el lector y luego iterar a través de él. Luego puede verificar si la columna existe. Esto será menos eficiente, pero no necesitará probar/atrapar bloques (por lo que tal vez sea más eficiente para sus necesidades).
Esto debería hacer el truco:
Public Shared Function ReaderContainsColumn(ByVal reader As IDataReader, ByVal name As String) As Boolean
For i As Integer = 0 To reader.FieldCount - 1
If reader.GetName(i).Equals(name, StringComparison.CurrentCultureIgnoreCase) Then Return True
Next
Return False
End Function
o (en C#)
public static bool ReaderContainsColumn(IDataReader reader, string name)
{
for (int i = 0; i < reader.FieldCount; i++) {
if (reader.GetName(i).Equals(name, StringComparison.CurrentCultureIgnoreCase)) return true;
}
return false;
}
: o)
Puede también utilizar IDataReader.GetSchemaTable
para obtener una lista de todas las columnas de el lector.
GetSchemaTable no muestra las columnas de la estructura de datos devuelta. – JamesEggers
Sí lo hace. El primer elemento de cada fila del lector. GetSchemaTable(). Las filas son los nombres de las columnas. es decir, reader.GetSchemaTable(). Filas [0] [0] me da el primer nombre de columna. –
La última vez que lo intenté, me dieron las columnas de schema_info. Aunque tendré que volver a intentarlo, ya que ha pasado un tiempo. – JamesEggers
La mejor solución que he usado está haciendo de esta manera:
DataTable dataTable = new DataTable();
dataTable.Load(reader);
foreach (var item in dataTable.Rows)
{
bool columnExists = item.Table.Columns.Contains("ColumnName");
}
Tratar de acceder a él a través lector [ "ColumnName"] y la comprobación de DBNull nulo o arrojará una excepción.
Enumerable.Range(0, reader.FieldCount).Any(i => reader.GetName(i) == "ColumnName")
- 1. si contiene cierto texto, luego ejecute jquery
- 2. Si el elemento contiene cierto texto
- 3. Rieles: ¿cómo validar un campo solo si otro campo tiene un cierto valor?
- 4. xRuta: Elija un elemento padre sólo si elemento secundario no contiene un cierto valor
- 5. Si el elemento padre no contiene cierto elemento hijo; jQuery
- 6. Detectando si se carga un HttpModule
- 7. NUnit: ¿Cuál es la forma más concisa de afirmar si un IEnumerable contiene un objeto de cierto tipo?
- 8. ¿Cómo verificar si existe un cierto ensamblaje?
- 9. ¿Cómo puedo verificar si una lista contiene un objeto de cierto tipo? C#
- 10. ¿Detecta si un NSString contiene ...?
- 11. Comprobando si un cierto tipo es un delegado de Acción
- 12. Restricción ÚNICA, solo cuando un campo contiene un valor específico
- 13. Comprobando la existencia y si existe, hay un cierto valor
- 14. ¿Cómo verificar si un objeto tiene cierto método/propiedad?
- 15. ¿Cómo comprobar que un ResultSet contiene un campo específicamente nombrado?
- 16. Rieles: cómo buscar_por un campo que contiene una cierta cadena
- 17. Detectando la entrada IME antes de ingresar presionado en Javascript
- 18. iterar un cierto número de veces sin almacenar el número de iteración en cualquier lugar
- 19. ¿Cómo comprobar si existe un directorio que contiene un archivo?
- 20. Averiguar si una lista de Objetos contiene algo con un valor de campo especificado?
- 21. Detectando si el caché de un navegador está lleno
- 22. Detectando si un navegador está en modo de pantalla completa
- 23. Get Substring - todo antes de cierto char
- 24. Eliminar un campo de documento antes de guardar en CouchDB?
- 25. Detectando un apagado programado
- 26. Detectando el segmento interceptado de un UISegmentedControl
- 27. SQLite campo de selección si el texto en el interior contiene un texto específico
- 28. Modo nulo para obtener valores de un IDataReader
- 29. ¿Detectando si se está reproduciendo la música?
- 30. Compruebe si la Lista de objetos contiene un objeto con un determinado valor de atributo
Que funcionará mal – DalSoft