2012-09-14 1 views
2

Envisagez la méthode FetchData ci-dessous. Il est conçu pour éviter de dupliquer le code de requête de la base de données chaque fois que vous souhaitez récupérer des données de la base de données.Évitez la duplication de code lors de la lecture/sérialisation à partir de DbDataReader?

List<MyData> myData = new List<MyData(); 
FetchData((IDataReader reader) => 
    { 
     myData.Add(new MyData(reader.GetString(0), reader.GetInt32(1))); 
    }, "usp_get_my_data"); 

Il fonctionne, mais ce serait bien si cette création d'objets pourrait en quelque sorte vivre dans la méthode FetchData.

Y a-t-il une meilleure approche?

Peut-être que FetchData peut être modifié pour retourner une liste d'un certain type X directement?

protected void FetchData(Action<IDataReader> processor, String query) 
{ 
    using (var connection = CreateConnection()) 
    { 
     connection.ConnectionString = ConnectionString; 
     connection.Open(); 

     using (var command = connection.CreateCommand()) 
     { 
      command.CommandType = CommandType.StoredProcedure; 
      command.CommandText = query; 

      using (IDataReader reader = command.ExecuteReader()) 
      { 
       while (reader.read()) 
       { 
        processor(reader); 
       } 
      } 
     } 
    } 
} 
+0

Le problème serait que FetchData aurait besoin maintenant de choses sur l'objet qu'il va créer pour y parvenir. Pourquoi ne pas faire de la création d'objet une partie de l'objet réel (dans ce cas, MyData) en utilisant une interface quelconque et la transmettre à FetchData. –

+0

Vous voulez dire comme une usine? Et un modèle pour permettre différents types de données? – l33t

+0

L'action du processeur qui a été transmise à FetchData devrait alors se dérouler dans MyData onbject. –

Répondre

2

L'utilisation de génériques peut-être?

protected IEnumerable<T> FetchData<T>(Func<IDataReader, T> processor, String query) 
{ 
    using (var connection = CreateConnection()) 
    { 
     connection.ConnectionString = ConnectionString; 
     connection.Open(); 

     using (var command = connection.CreateCommand()) 
     { 
      command.CommandType = CommandType.StoredProcedure; 
      command.CommandText = query; 

      using (IDataReader reader = command.ExecuteReader()) 
      { 
       while (reader.read()) 
       { 
        yield return processor(reader); 
       } 
      } 
     } 
    } 
} 

vous pouvez utiliser l'énumération mais vous voulez:

var myData = FetchData<MyData>(reader => new MyData(reader.GetString(0), reader.GetInt32(1)), "usp_get_my_data").ToList(); 
+0

Absolument génial! Merci. – l33t

1

Vous pouvez jeter un oeil à Dapper.Net qui est ORM seul fichier avec trois aides différentes:

  1. exécuter une requête et mappez les résultats à une liste fortement typée
  2. Exécuter une requête et la mapper à une liste d'objets dynamiques
  3. exécuter une commande qui renvoie aucun résultat

patterns de conception utilisés pour construire cette miro-ORM sont si utiles. Dapper.Net is currently being used in StackOverflow.

+0

Intéressant! Se penchera sur cela dans les futures implémentations! – l33t

Questions connexes