web-dev-qa-db-fra.com

C # DataRow Vide-check

J'ai eu ceci:

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

Ensuite, j'ajoute des données à la ligne (ou pas) . Beaucoup de code, je ne sais vraiment pas s'il y a quelque chose à l'intérieur de la ligne . Dépend de l'entrée (j'importe de certains fichiers) ..__ J'aimerais faire quelque chose comme:

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

Existe-t-il un bon moyen de vérifier si chaque cellule du DataRow est vide? Ou devrais-je le faire, et les vérifier un par un?

16
Ash

Une méthode simple dans le sens de:

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

Devrait vous donner ce que vous cherchez, et pour que ce soit "sympa" (comme il n’existe rien dans le Framework), vous pouvez le résumer comme une méthode d’extension, et ensuite votre code :

if (datarow.AreAllColumnsEmpty())
{
}
else
{
}
24
Rob

J'ai créé un assistant (dans une classe statique que j'ai appelée DataRowHelpers, inventif, je sais) appelé IsEmpty comme suit:

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

Les autres réponses ici sont correctes. J'ai juste senti que le mien était concis dans son utilisation succincte de Linq to Objects. En passant, cela est vraiment utile avec l'analyse Excel, car les utilisateurs peuvent visionner une ligne en bas de la page (des milliers de lignes) sans se soucier de l'impact sur l'analyse des données.

Dans la même classe, je mets tous les utilitaires que je trouve utiles, tels que les analyseurs, de sorte que si le champ contient du texte dont vous savez qu'il devrait être un nombre, vous pouvez l'analyser couramment. Astuce mineure pour les débutants. (Quelqu'un à SO, vraiment? Nah!)

Dans cet esprit, voici une version améliorée:

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());
}

Vous avez maintenant un autre assistant utile, IsNullEquivalent, qui peut être utilisé dans ce contexte et dans tout autre. Vous pouvez également inclure des éléments tels que "n/a" ou "TBD" si vous savez que vos données ont des espaces réservés de ce type.

9
Jack Pines

Je préfère l'approche de Tommy Carlier, mais avec un peu de changement.

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

  return true;

Je suppose que cette approche semble plus simple et plus brillante.

7
Thinhbk
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;
}
5
Tommy Carlier

Je sais que cela a déjà été répondu et que c'est une vieille question, mais voici une méthode d'extension pour faire de même

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()));            
    }
}

Et vous l'utilisez comme ceci:

if (dr.AreAllCellsEmpty())
// etc
3
Icarus

Vous pouvez utiliser ceci:

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

IsNotEmpty(cell) serait votre propre implémentation, vérifiant si les données sont nulles ou vides, en fonction du type de données contenu dans la cellule. Si c'est une simple chaîne, elle pourrait ressembler à ceci:

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

Néanmoins, il vérifie essentiellement que chaque cellule est vide et vous permet de savoir si toutes les cellules de la ligne sont vides.

2
Aaron

DataTable.NewRow initialisera chaque champ pour:

  • la valeur par défaut pour chaque DataColumn (DataColumn.DefaultValue)

  • à l'exception des colonnes à incrémentation automatique (DataColumn.AutoIncrement == true), qui seront initialisées à la valeur d'incrémentation suivante.

  • et les colonnes d'expression (DataColumn.Expression.Length > 0) constituent également un cas particulier; la valeur par défaut dépendra des valeurs par défaut des colonnes sur lesquelles l'expression est calculée.

Donc, vous devriez probablement vérifier quelque chose comme:

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;
}

Je vais laisser la version LINQ en exercice :)

1
Joe

Je l'ai fait comme ça:

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
Jeff

D'après les informations dont je dispose, aucune méthode ne le fait dans le cadre. Même s'il y avait un soutien pour quelque chose comme cela dans le cadre, ce serait essentiellement faire la même chose. Et ce serait regarder chaque cellule dans le DataRow pour voir si elle est vide. 

0
Will

Une meilleure solution consisterait peut-être à ajouter une colonne supplémentaire qui est automatiquement définie sur 1 sur chaque ligne. Dès qu'il y a un élément qui n'est pas nul, changez-le en 0.

puis 

If(drEntitity.rows[i].coulmn[8] = 1)
{
   dtEntity.Rows.Add(drEntity);
}
 else
 {
   //don't add, will create a new one (drEntity = dtEntity.NewRow();)
 }
0
Zyon