2010-05-05 3 views
0

Quelle serait la bonne façon de modifier les valeurs à la volée lorsqu'elles sont chargées dans un DataTable par SqlAdapter.Fill()?Modifier les valeurs à la volée pendant SqlAdapter.Fill()

J'ai globalisé les messages de mon application. Un entier indiquant le type d'événement et les données sérialisées pertinentes pour l'événement est stocké dans la base de données comme indiqué ci-dessous. Lorsque j'affiche les événements consignés via un contrôle DataGridView à l'utilisateur, j'interpole les données dans une chaîne de mise en forme.

event_type event_timestamp  event_details 
============================================ 
3   2010-05-04 20:49:58 jsmith 
1   2010-05-04 20:50:42 jsmith 
... 

Je parcours actuellement les lignes de DataTable pour formater les messages.

public class LogDataTable : DataTable 
{ 
    public LogDataTable() 
    { 
     Locale = CultureInfo.CurrentCulture; 
     Columns.AddRange(new DataColumn[] { 
      new DataColumn("event_type", typeof(Int32)), 
      new DataColumn("event_timestamp", typeof(DateTime)), 
      new DataColumn("event_details", typeof(String))}); 
    } 
} 

... 
using (SqlDataAdapter adapter = new SqlDataAdapter(...)) 
{ 
    adapter.SelectCommand.Parameters.AddRange(new Object[] { 
     ... 
    }); 
    adapter.Fill(table); 
} 
foreach (DataRow row in table.Rows) 
{ 
    switch ((LogEventType)row["event_type"]) 
    { 
     case LogEventType.Create: 
      row["event_details"] = String.Format(Resources.Strings.LogEventCreateMsg, row["event_details"]; 
      break; 
     case LogEventType.Create: 
      row["event_details"] = String.Format(Resources.Strings.LogEventCreateMsg, row["event_details"]; 
      break; 
     ... 

Le résultat final tel qu'affiché ressemblerait à:

Type Date and Time  Details 
==================================================================== 
[icon] 2010-05-04 20:49:58 Failed login attempt with username jsmith 
[icon] 2010-05-04 20:50:42 Successful login with username jsmith 
... 

Il semble inutile de itérer le jeu de résultats twice-- une fois que la table est remplie par l'adaptateur, et à nouveau pour effectuer les remplacements. Je voudrais vraiment faire le remplacement à la volée dans ma classe LogDataTable comme il est peuplé.

J'ai essayé de remplacer une méthode OnRowChanging dans LogDataTable, ce qui déclenche une exception InRowChangingEventException.

protected override void OnRowChanging(DataRowChangeEventArgs e) 
{ 
    base.OnRowChanging(e); 
    switch ((LogEventType)row["event_type"]) 
    ... 

J'ai essayé de forcer une méthode OnRowChanged, qui jette un StackOverflowException (je suppose changer redéclenche l'annonce de la méthode infinitum?).

J'ai essayé de surcharger une méthode OnTableNewRow, qui ne génère pas d'exception mais qui semble ne pas être invoquée (je suppose que lorsqu'un utilisateur ajoute une ligne dans la vue, ce que j'ai empêché).

J'apprécierais grandement toute aide que n'importe qui peut me donner.

Répondre

0

IMO, ce que vous faites actuellement va bien. Vous pouvez très bien modifier vos éléments DataTable en mémoire une fois qu'ils sont remplis plutôt que de les modifier à la volée car cela peut dégrader vos performances car il interrompt l'opération d'E/S. D'autre part, si vous êtes l'administrateur DB, vous pouvez mieux ETL votre première colonne :)

+0

Merci. Point intéressant sur l'opération IO. Existe-t-il un événement déclenché lorsque adaptateur.Fill() est terminé? Cela me permettrait toujours de déplacer le code dans la classe LogDataTable et de faire en sorte que l'interpolation se fasse de façon transparente, même si elle est répétée après que la table ait été remplie. – Timothy

+0

Je ne sais pas si vous avez un événement après le remplissage. Trouvez-vous vraiment un problème en insérant une instruction d'appel de méthode après 'adapter.Fill (table);'? :) – Amsakanna

Questions connexes