2009-02-20 7 views
1

J'ai quelques prédicats en construction dynamique qui ont la signature suivante passe par en tant que paramètres en fonction:Dynamiquement recherche à l'aide LINQ et créé dynamiquement prédicats

Expression<Func<TblTableR, bool>> TableRPredicate, 
Expression<Func<TblTableN, bool>> suspectNamesPredicate, 
Expression<Func<TblTableS, bool>> TableSPredicate, 
Expression<Func<TblTableI, bool>> suspectTableIPredicate, 

Je suis en train d'interroger en utilisant les éléments suivants:

var registries = (from r in db.TblTableR.Where(TableRPredicate) 
join s in db.TblTableS.Where(TableSPredicate) 
     on r.TblTableRID equals s.TblTableSTableRID into ss 
from suspects in ss.DefaultIfEmpty() 
    join si in db.TblTableI.Where(suspectTableIPredicate) 
     on suspects.TblTableSIndexCardID equals si.TblTableIID into sisi 
    from suspectTableI in sisi.DefaultIfEmpty() 
    join sn in db.TblTableN.Where(suspectNamesPredicate) 
     on suspectTableI.TblTableIID equals sn.TblTableNIndexCardID into snsn 
    from suspectNames in snsn.DefaultIfEmpty() 
    select r.TblTableRID).Distinct(); 

Cela a pour résultat de mettre tout produit « where » dans la déclaration REJOIGNEZ par exemple:

left outer join tblTableI on tblTableITableRID = tblTableRID 
    AND (expression created by predicate) 

Ce qui se passe réellement, c'est que le SQL final créé est incorrect. Il crée le type suivant de sql

select * from table1 left outer join table2 on field1 = field2 
    AND field3 = 'CRITERIA' 

Il est cette clause AND à la fin qui est le problème - finissant par revenir trop de lignes. Essentiellement je voudrais obtenir la clause where dans la déclaration et ne pas la coller dans la jointure.

Quelque chose comme ceci:

select * from table1 left outer join table2 on field1 = field2 
    WHERE field3 = 'CRITERIA' 

J'ai essayé d'ajouter une clause where comme suit:

... 
... 
... 
select r.TblTableRID).Where(TableRPredicate).Distinct(); 

mais qui ne compilera pas en raison des paramètres génériques de chaque attribut.

Si je modifie ma requête LINQ pour ne sélectionner que dans une table et utiliser un prédicat, la clause WHERE est générée correctement.

Des idées?

Répondre

1

(clarification après publication)

Étape 1; changer la sélection finale pour sélectionner les trois entités dans un type anonyme; pour moi (test sur Northwind), c'est-à-dire:

select new {emp, cust, order}; 

Étape 2; appliquez vos filtres à ceci en utilisant la méthode d'extension que j'ai ajoutée ci-dessous; pour moi ce filtrage ressemble à:

var qry2 = qry.Where(x => x.emp, employeeFilter) 
      .Where(x => x.cust, custFilter) 
      .Where(x => x.order, orderFilter); 

Étape 3; maintenant sélectionner les entités/entités que vous voulez en fait de cette filtrée requête:

var data = qry2.Select(x => x.order) 

Et voici la méthode d'extension:

static IQueryable<T> Where<T,TValue>(
    this IQueryable<T> source, 
    Expression<Func<T, TValue>> selector, 
    Expression<Func<TValue, bool>> predicate) 
{ 
    var row = Expression.Parameter(typeof (T), "row"); 
    var member = Expression.Invoke(selector, row); 
    var lambda = Expression.Lambda<Func<T, bool>>(
     Expression.Invoke(predicate, member), row); 
    return source.Where(lambda); 
} 
+0

Marc, J'ai mis à jour le poste pour faire des choses un peu plus clair . Peter –

+0

OK; J'espère que cette mise à jour corrige les choses pour vous. –

+0

Merci Marc, ça a résolu le problème! –

Questions connexes