2010-12-14 9 views
1

Disons que j'ai la requête suivante:subsonique - convertir une requête LINQ to SQL requête/DataReader

int x = 5; 
var result = from p in db.products 
      where p.CategoryId == x 
      select p; 

int count = result.Count(); 
List<product> products = result.ToList(); 

C'est ce que j'ai maintenant. Mais Aditionally je dois avoir un DataReader de résultat:

// that's what I need: 
var reader = ConvertSubSonicLinqQueryToDataReader(result); 

Comment puis-je convertir la déclaration LINQ à quelque chose que je peux travailler? Un DataReader ou un DbCommand ou même un sql simple avec une liste de paramètres.

Je sais que SubSonic peut le faire (puisqu'il traduit la requête en plain sql de toute façon) mais je n'ai rien trouvé dans les méthodes accessibles au public pour le moment.

Des suggestions?

+0

Que voulez-vous faire avec DataReader? Peut-être qu'il y a quelque chose que nous pouvons suggérer à la place. –

+0

Je dois passer un DataReader à une méthode tierce (il suffirait de compiler la requête linq pour une instruction sql simple afin que je puisse utiliser une InlineQuery) –

Répondre

1

La conversion de la requête LINQ est la mauvaise approche. LINQ renvoie les résultats à un niveau d'abstraction supérieur à celui d'un DataReader.

Il y a aussi le problème de l'exécution différée de sorte que votre requête LINQ peut ne pas être exécutée comme une seule instruction SQL de toute façon. Évaluer plutôt que d'utiliser une instruction LINQ pourquoi ne pas simplement utiliser un SqlQuery à la place?

var qry = new Select().From(Product.Schema).Where(Product.CategoryIdColumn).IsEqualTo(x); 

return qry.ExecuteReader(); 

Edit:
vient de voir que vous utilisez SubSonic3 (non 2 comme le code ci-dessus serait pour), mais l'utilisation abusive potentielle de LINQ et la duplication des travaux est toujours valable.

+0

Je sais que Linq Query est une expression en premier lieu et get exécuté si nécessaire (c'est pourquoi j'ai inclus deux instructions, 'Count()' et 'ToList()' dans mon exemple, ce qui donne deux requêtes différentes). SubSonic doit avoir la capacité de convertir un IQuerable spécifique en quelque chose comme un 'IDataReader' ou' IDbCommand' car à la fin de la journée subsonic doit l'exécuter contre un dbms. Peut-être que cette méthode n'est pas dans l'interface publique atm mais je suis sûr que je vais le comprendre d'une manière ou d'une autre. Btw. C'est difficile à expliquer, mais je ne peux pas utiliser l'outil de requête parce que j'obtiens l'IQuerable d'une autre source. –

+0

@SchlaWiener Pour transformer un 'IQueryable ' en un 'IDataReader' va prendre un peu de creuser dans la source de' SubSonic.core'. Je commencerais par regarder 'SubSonic.Linq.Strucutre.QueryCompiler' et' SubSonic.SqlGenerator'. –

0

Le code qui crée l'objet à partir de DataReader peut être trouvé dans DbDataProvider.ToEnumerable. Il est appelé depuis la méthode Execute de DbQueryProvider (ligne 227). La meilleure façon de "comprendre" la magie LINQ est de placer quelques points d'arrêt sur les méthodes DbQueryProvider.