2017-08-22 3 views
1

J'utilise Dapper avec la base de données ClickHouse (https://clickhouse.yandex/). C'est une base de données orientée colonne. Cela fonctionne bien, mais le résultat de la requête peut être divisé en plusieurs blocs, donc je devrais utiliser NextResult pour récupérer toutes les données. Exemple de code:NextResult avec Dapper

public static void ExecuteSQL(ClickHouseConnection connection, string sql) 
{ 
    using (var reader = connection.CreateCommand(sql).ExecuteReader()) 
    { 
     do 
     { 
      while (reader.Read()) 
      { 
         ... 
      } 
     } 
     while (reader.NextResult()); 
    } 
} 

Je suis en train d'utiliser Dapper. Pour appeler NextResult je devrais utiliser la méthode QueryMultiple. J'ai fait le code:

public static void ExecuteDapperQuery<T>(ClickHouseConnection connection, string sql) 
{ 
    Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true; 
    using (var dapperQuery = connection.QueryMultiple(sql)) 
    { 
     do 
     { 
      var list = dapperQuery.Read<T>().ToList(); 
      ... /* Do something with list */ 
     } 
     while (true); 
    } 
} 

mais ce code génère une exception ObjectDisposedException lorsque toutes les données sont récupérées et le lecteur de SQL devient nulle. J'ai besoin de savoir s'il y a le moyen de savoir quand je devrais finir l'itération? Ou existe-t-il un autre moyen de travailler avec cette base de données?

+1

Quelle exception faut-il jeter? Tu dois être plus précis. – DavidG

+0

C'est à cause de la boucle infinie do/while. Vous pouvez uniquement appeler read pour le nombre d'instructions exécutées. – Nkosi

+0

L'exception est 'ObjectDisposedException' et se produit lorsque le lecteur est null. Je ne sais pas comment je peux vérifier si NextResult a renvoyé true ou false. –

Répondre

0

C'est à cause de la boucle infinie do/while. Vous pouvez uniquement appeler read pour le nombre d'instructions exécutées.

J'ai besoin de savoir s'il y a le moyen de savoir quand je devrais terminer l'itération?

Assurez-vous que le lecteur n'a pas déjà été consommé avant de lire l'ensemble

using (var gridReader = connection.QueryMultiple(sql)) { 
    while(!gridReader.IsConsumed) { //<-- query multiple until consumed 
     var list = gridReader.Read<T>().ToList(); 
     ... /* Do something with list */ 
    } 
}