2010-02-24 397 views
14

Tengo esto:C# DataRow vacío a comprobar

DataTable dtEntity = CreateDataTable(); 
drEntity = dtEntity.NewRow(); 

Luego añadir los datos de la fila (o no). Hay un montón de código, realmente no sé si hay algo dentro de la fila. Depende de la entrada (estoy importando desde algunos archivos). me gustaría hacer algo como:

if (drEntity`s EVERY CELL IS NOT EMPTY) 
{ 
    dtEntity.Rows.Add(drEntity); 
} 
else 
{ 
    //don't add, will create a new one (drEntity = dtEntity.NewRow();) 
} 

¿Hay alguna buena manera de comprobar si todas las células del DataRow está vacía? O debería foreach, y revisarlos uno por uno?

Respuesta

21

Un método simple a lo largo de las líneas de:

bool AreAllColumnsEmpty(DataRow dr) 
{ 
if (dr == null) 
{ 
    return true; 
} 
else 
{ 
    foreach(var value in dr.ItemArray) 
    { 
    if (value != null) 
    { 
     return false; 
    } 
    } 
    return true; 
} 
} 

debe darle lo que está buscando, y para que sea "buena" (ya que no hay nada por lo que yo sé, en el Marco), usted podría envolverlo como un método de extensión, y luego su código resultante sería:

if (datarow.AreAllColumnsEmpty()) 
{ 
} 
else 
{ 
} 
+0

En realidad, la condición dentro del foreach debería tener más que eso. Sólo probado :) algo como: (! value.ToString() = "") if (! valor = null) { si { return false; } } – Ash

+0

@Swoosh, supongo que eso depende de cuál sea tu definición de "vacío". Fui con "nulo". =) – Rob

+1

Esto no tiene en cuenta los valores predeterminados de las columnas, ni las columnas con incremento automático - ver mi respuesta. – Joe

0

AFAIK, no existe un método que lo haga en el marco. Incluso si hubiera apoyo para algo como esto en el marco, esencialmente estaría haciendo lo mismo. Y eso sería mirar cada celda en el DataRow para ver si está vacío.

1

podría utilizar este:

if(drEntity.ItemArray.Where(c => IsNotEmpty(c)).ToArray().Length == 0) 
{ 
    // Row is empty 
} 

IsNotEmpty(cell) sería su propia implementación, verificando si los datos son nulos o están vacíos, según el tipo de datos en la celda. Si se trata de una cadena simple, que podría terminar buscando algo como esto:

if(drEntity.ItemArray.Where(c => c != null && !c.Equals("")).ToArray().Length == 0) 
{ 
    // Row is empty 
} 
else 
{ 
    // Row is not empty 
} 

Aún así, es esencialmente comprueba cada celda de vacío, y le permite saber si todas las celdas de la fila están vacíos.

+0

Lo único que no me gusta de este enfoque es que realmente tiene que * pensar * para determinar qué hace el código, mientras que "if (IsDataRowEmpty (drEntity)) {} else {}" con la * implementación * movida a el método IsDataRowEmpty es mucho más fácil de leer. – Rob

0

Quizás una solución mejor sería agregar una columna adicional que se establece automáticamente en 1 en cada fila. Tan pronto como hay un elemento que no es nulo cambio a un 0.

continuación

If(drEntitity.rows[i].coulmn[8] = 1) 
{ 
    dtEntity.Rows.Add(drEntity); 
} 
else 
{ 
    //don't add, will create a new one (drEntity = dtEntity.NewRow();) 
} 
5
public static bool AreAllCellsEmpty(DataRow row) 
{ 
    if (row == null) throw new ArgumentNullException("row"); 

    for (int i = row.Table.Columns.Count - 1; i >= 0; i--) 
    if (!row.IsNull(i)) 
     return false; 

    return true; 
} 
0

lo hice así:

var listOfRows = new List<DataRow>(); 
foreach (var row in resultTable.Rows.Cast<DataRow>()) 
{ 
    var isEmpty = row.ItemArray.All(x => x == null || (x!= null && string.IsNullOrWhiteSpace(x.ToString()))); 
    if (!isEmpty) 
    { 
     listOfRows.Add(row); 
    } 
} 
+0

Debería verificar si es! IsEmpty y luego agregar la fila a la lista. – Jeff

6

prefiero enfoque de Tommy Carlier, pero con un pequeño cambio.

foreach (DataColumn column in row.Table.Columns) 
    if (!row.IsNull(column)) 
     return false; 

    return true; 

Supongo que este enfoque se ve más simple y brillante.

1

DataTable.NewRow inicializará cada campo para:

  • el valor por defecto para cada DataColumn (DataColumn.DefaultValue)

  • excepto para las columnas de incremento automático (DataColumn.AutoIncrement == true), que se inicializa a la siguiente auto -incremento de valor

  • y columnas de expresión (DataColumn.Expression.Length > 0) son también un caso especial; el valor predeterminado dependerá de los valores predeterminados de las columnas en las que se calcula la expresión.

Así que probablemente debe comprobar algo como:

bool isDirty = false; 
for (int i=0; i<table.Columns.Count; i++) 
{ 
    if (table.Columns[i].Expression.Length > 0) continue; 
    if (table.Columns[i].AutoIncrement) continue; 
    if (row[i] != table.Columns[i].DefaultValue) isDirty = true; 
} 

Voy a dejar la versión de LINQ como un ejercicio :)

3

Sé que esto ya ha sido contestada y que es una vieja pregunta, pero aquí es un método de extensión para hacer lo mismo:

public static class DataExtensions 
{ 
    public static bool AreAllCellsEmpty(this DataRow row) 
    { 
     var itemArray = row.ItemArray; 
     if(itemArray==null) 
      return true; 
     return itemArray.All(x => string.IsNullOrWhiteSpace(x.ToString()));    
    } 
} 

Y que lo utilizan de esta manera:

if (dr.AreAllCellsEmpty()) 
// etc 
7

creé un ayudante (en una clase estática llamé DataRowHelpers, inventivo, lo sé) llama IsEmpty de la siguiente manera:

public static bool IsEmpty(this DataRow row) 
{ 
    return row == null || row.ItemArray.All(i => i is DBNull); 
} 

Las otras respuestas aquí son correctos. Simplemente sentí que la mía prestaba brevedad en su uso sucinto de Linq a los Objetos. Por cierto, esto es realmente útil junto con el análisis de Excel, ya que los usuarios pueden virar en una fila en la página (miles de líneas) sin tener en cuenta cómo afecta el análisis de los datos.

En la misma clase, puse otros ayudantes que encontré útiles, como analizadores, de modo que si el campo contiene texto que sabe que debe ser un número, puede analizarlo con fluidez. Consejo profesional de menor importancia para cualquier persona nueva en la idea. (?! Cualquier persona en el SO, realmente NAH)

Con esto en mente, aquí es una versión mejorada:

public static bool IsEmpty(this DataRow row) 
{ 
    return row == null || row.ItemArray.All(i => i.IsNullEquivalent()); 
} 

public static bool IsNullEquivalent(this object value) 
{ 
    return value == null 
      || value is DBNull 
      || string.IsNullOrWhiteSpace(value.ToString()); 
} 

Ahora tiene otro ayudante útil, IsNullEquivalent que se puede utilizar en este contexto y cualquier otra , también. Puede ampliar esto para incluir cosas como "n/a" o "TBD" si sabe que sus datos tienen marcadores de posición como ese.

Cuestiones relacionadas