Exécution d'une partie d'une requête IQueryable et renvoi du reste à Linq for Objects

c# expression-trees iqueryable linq

Question

J'ai un fournisseur Linq qui récupère avec succès les données de la source de données choisie, mais ce que j'aimerais faire maintenant que j'ai mes résultats filtrés, est de permettre à Linq to Objects de traiter le reste de l'arborescence Expression (pour des tâches telles que Joins, projection etc)

Je pensais pouvoir remplacer la constante d'expression contenant IQueryProvider par les ensembles de résultats IEnumerable via ExpressionVisitor, puis renvoyer cette nouvelle expression. Également renvoyer le fournisseur IEnumerable de mon IQueryable ... mais cela ne semble pas fonctionner :-(

Des idées?

Edit: Quelques bonnes réponses ici, mais vu la forme ...

var qry = from c in MyProv.Table<Customer>()
          Join o in MyProv.Table<Order>() on c.OrderID equals o.ID
          select new 
          {
            CustID = c.ID,
            OrderID = o.ID
          }

Dans mon fournisseur, je peux facilement récupérer les 2 résultats de Clients et Commandes. Si les données provenaient d'une source SQL, je construirais et transmettrais simplement la syntaxe SQL Join, mais dans ce cas, les données ne proviennent pas d'une source SQL. besoin de faire la jointure dans le code ... mais comme je l'ai dit, j'ai les 2 ensembles de résultats, et Linq to Objects peut faire une jointure ... (et plus tard la projection), ce serait bien de simplement remplacer les constantes Expression MyProv.Table<Customer> et MyProv.Table<Order> avec List<Customer> et List<Order> puis laissez un fournisseur List<> traiter l’expression ... est-ce possible? Comment?

Réponse acceptée

Le genre de chose que je recherchais remplaçait la constante Queryable <> dans l'arbre d'expression par un résultat concret IEnumerable (ou IQueryable via .AsQueryable ()) ... il s'agit d'un sujet complexe qui n'a probablement de sens que pour Linq Les rédacteurs fournisseurs qui sont à genoux dans les visiteurs de l'arbre d'expression, etc.

J'ai trouvé un extrait de la procédure pas à pas qui fait quelque chose comme ce que je suis après, cela me donne un moyen d'avancer ...

using System;
using System.Linq;
using System.Linq.Expressions;

namespace LinqToTerraServerProvider
{
    internal class ExpressionTreeModifier : ExpressionVisitor
    {
        private IQueryable<Place> queryablePlaces;

        internal ExpressionTreeModifier(IQueryable<Place> places)
        {
            this.queryablePlaces = places;
        }

        internal Expression CopyAndModify(Expression expression)
        {
            return this.Visit(expression);
        }

        protected override Expression VisitConstant(ConstantExpression c)
        {
            // Replace the constant QueryableTerraServerData arg with the queryable Place collection.
            if (c.Type == typeof(QueryableTerraServerData<Place>))
                return Expression.Constant(this.queryablePlaces);
            else
                return c;
        }
    }
}

Réponse populaire

Les deux réponses précédentes fonctionnent, mais la lecture est meilleure si vous utilisez AsEnumerable () pour convertir l'IQueryable en IEnumerable:

// Using Bob's code...
var result = datacontext.Table
   .Where(x => x.Prop == val)
   .OrderBy(x => x.Prop2)
   .AsEnumerable()  //  <---- anything after this is done by LINQ to Objects
   .Select(x => new { CoolProperty = x.Prop, OtherProperty = x.Prop2 });

MODIFIER:

// Using Bob's code...
var result = datacontext.Table
   .Where(x => x.Prop == val)
   .OrderBy(x => x.Prop2)
   .AsEnumerable()  //  <---- anything after this is done by LINQ to Objects
   .Select(x => new { CoolProperty = x.Prop, OtherProperty = x.Prop2 });



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi