2010-01-27 4 views
0

J'ai une requête LINQ to SQL sur l'entité qui a EntitySet des enfants que je dois trier sur certains champs enfants, à savoir utiliser cette requête:problème de tri LINQ to SQL dynamique

var query = from p in context.Patients 
      let order = p.Lab_Orders.First() 
      orderby order.Order_Date 
      select p; 

Cette requête fonctionne bien, mais comment pourrais-je le modifier pour utiliser la méthode DBLQ OrderBy ce que je passerais comme un paramètre de tri en cours d'exécution?

Répondre

1

Si par DLINQ vous voulez dire Requête Dynamique, alors vous ne pouvez pas utiliser les expressions de requête comme ça, vous devez utiliser des méthodes d'extension avec lambdas. Vous pouvez commencer par une expression de requête, mais vous devez passer par la suite la parole à lambda:

IEnumerable<Patient> GetPatients(string orderSortField) 
{ 
    var query = 
     from p in context.Patients 
     select new 
     { 
      Patient = p, 
      FirstOrder = p.Lab_Orders.First() 
     }; 
    return p.OrderBy(orderSortField).Select(p => p.Patient); 
} 

Appelez avec:

var patientsByOrderDate = GetPatients("FirstOrder.Order_Date"); 
+0

Merci pour la réponse. C'est exactement ce que je voulais dire - Dynamic LINQ. Ssory sur la confusion, en quelque sorte je pensais que tout le monde sait ce que c'est puisque nous utilisons cette terminologie sur mon lieu de travail :-) Juste une question - parfois nous avons de nouveaux patients sans ordres de laboratoire associés pour le moment. Évidemment, dans ce cas, je ne me soucie pas d'un tel tri. Dois-je remplacer First() par FirstOrDefault()? – Victor

+0

@Victor: Si vous remplacez par 'FirstOrDefault' et essayez de trier' FirstOrder.Order_Date', vous obtiendrez une 'NullReferenceException' si des enregistrements n'ont pas d'ordre. S'il est possible qu'il n'y ait pas de commandes, je suggère de séparer explicitement la date de la commande, comme dans: 'FirstOrderDate = p.Lab_Orders.FirstOrDefault (o => (DateTime?) O.Order_Date)', puis triez sur '' FirstOrderDate'. – Aaronaught

+0

Il est possible qu'il n'y ait pas de commandes mais que de nouveaux patients soient traités séparément, c'est-à-dire que tous les patients aient des ordres, ou qu'ils ne le fassent pas tous. Mais, je pense que votre conseil est valable, alors je le ferai. – Victor

0

Essayez d'ajouter le « OrderBy » à l'arbre d'expression:

var query = from p in context.Patients 
      let order = p.Lab_Orders.First() 
      select p; 
var x = Expression.Parameter(query.ElementType, "x"); 
string sortName = "order.Order_Date"; 
var selector = Expression.Lambda(Expression.PropertyOrField(x, sortName), x); 
query = query.Provider.CreateQuery(
     Expression.Call(typeof(Queryable), "OrderBy", 
       new Type[] { query.ElementType, selector.Body.Type }, 
       query.Expression, selector) 
     ) as IQueryable<Patients>; 

Nécessite l'espace de noms "System.Linq.Expressions".

+0

Merci pour votre réponse. Bien que j'aime créer et utiliser des expressions, je ne pense pas qu'on en ait besoin ici, car LINQ dynamique en crée une pour vous. – Victor

0

Utilisez le AsQueryable() après la déclaration initiale -

var query = from p in context.Patients 
      let order = p.Lab_Orders.First()   
      select p; 

query = query.AsQueryable().OrderBy(x => x.Lab_Orders.First().OrderDate); 
+0

Merci pour votre réponse. Besoin d'utiliser Dynamic LINQ – Victor