7
votes

ADO.net: Vérifiez si le nom du champ existe sur IdataRecord

Y a-t-il une meilleure façon d'obtenir la valeur de Field_Name à partir d'un IDataRecord uniquement si le nom de Field_Name existe dans l'IDataRecord, j'utilise actuellement un ESSAY {...} Catch {...} strong> Bloc, mais c'est une sorte de sur erreur de reprise suivant em>. Certaines alternatives?

public static Tresult ValueIfExists2<Tresult>(this IDataRecord record, string field_name)
{
    for (int index = 0; index < record.FieldCount; index++)
    {
        if (record.GetName(index).Equals(field_name, StringComparison.InvariantCulture))
        {
            return record.Value<Tresult>(record.GetOrdinal(field_name));
        }
    }
    return default(Tresult);
}


2 commentaires

Vous devez utiliser stringcomparoison.ordinalisorecase car les noms de colonnes peuvent être dans tous les cas.


duplicaté possible de Détection Si un iDatreader contient un certain champ avant Itération


4 Réponses :


2
votes

Regardez cette question étroitement liée à une approche viable des tests d'une existence d'un champ. Notez que si vous imitez une collection de résultats, il est probablement préférable de vérifier la colonne une fois, plutôt que sur chaque itération.

Vérifier le nom de la colonne dans un objet SQLDatreader < / p>


1 commentaires

Cela signifie que pour le moment, la seule manière pour vérifier l'existence de champs dans l'interface [IdataRecord] est itération. Ensuite, le problème est de mettre en œuvre le meilleur algorithme de recherche pour IdataRecord.



16
votes

Vous avez raison, que des exceptions ne doivent pas être utilisées pour le flux de programme normal.

La méthode getordininal est destinée à des situations où vous savez quels champs vous obtenez, et si un champ est manquant. Une erreur qui devrait entraîner une exception.

Si vous ne savez pas quels champs vous entrez dans le résultat, vous devez éviter la méthode getordinal . Vous pouvez plutôt obtenir tous les noms et leur index dans un dictionnaire que vous pouvez utiliser comme remplacement de la méthode getordininal : xxx

Vous pouvez utiliser le ContainkeyKey Pour vérifier si le nom existe dans le dictionnaire, ou la méthode trygetValue pour vérifier si le nom existe et obtenez-en son index, il fait en une seule opération.

La méthode getordininal fait d'abord une facture Senstivee recherche du nom, et si cela échoue, il fait une recherche insensète de cas. Ce n'est pas fourni par le dictionnaire, donc si vous voulez que le comportement exact, vous préférez stocker les noms dans un tableau et écrire une méthode pour la boucler lorsque vous souhaitez trouver l'index.


3 commentaires

Je pense que l'interface [IdataRecord] manque pour une méthode de test de l'existence des éléments. J'ai utilisé quelque chose comme votre code pour Visual Basic 6 Recherches, mais j'étais de l'idée que .NET a déjà quelque chose pour traiter cela.


@Arcebrito: Autant que je puisse dire qu'il n'y a pas de méthode pour vérifier spécifiquement l'existence d'un champ dans les classes de mise en œuvre telles que sqldatreader non plus. Il vous suffit d'utiliser getname pour savoir quels champs il y a.


Une version plus linqy: énumérable.Range (0, record.fieldcount) .ToDictionary (i => record.getname (i), i => i)



1
votes

J'utilise toujours l'approche suivante pour idatareader (puisque la plupart idatareecord vous obtenez des lecteurs) lecteur.getschematetable (). Colonnes.Contains ("champ")

Bien sûr, si vous avez un authentique idatareecord , cela échouera si vous essayez de le jeter à idatareader et ce n'est pas un.


3 commentaires

Dans mon cas, j'utilise un modèle de mapper pour créer des objets en passant comme argument l'IDataRecord afin que je ne puisse pas utiliser votre approche suggérée; En revanche, il faut obtenir la métadonnée de la table de base de données qui pourrait être plus chère que d'itération de la collection de champs dans le but de vérifier l'existence sur le terrain.


C'est en fait moins cher généralement. Les métadonnées ont été saisies au moins une fois dans le cas du sqldatareader , et il est mis en cache après, il continue de lire la même variable.


Cela vérifie la colonne de la table de schéma, pas la table de données réelle! Retourne toujours faux! Vérifiez cette réponse: Stackoverflow.com/a/813713/1070906



3
votes

avec une ligne:

bool exists = Enumerable.Range(0, dataRecord.FieldCount).Any(x => dataRecord.GetName(x) == "columnName"); // or with OrdinalIgnoreCase


0 commentaires