2010-12-04 36 views
0

je recevais des lignes de répéter cette requête LINQ:Linq bizarrerie

   public static Func<DataContext, string, IQueryable<Building>> 
      GearFilteredBuildings = 
       CompiledQuery.Compile((DataContext db, string filter) => 
        from b in db.Building 
         join r in db.Router on b equals r.Building 
        orderby !b.Active 
        where filter.Length == 5 && r.Name.Substring(1, 5).ToLower() == filter 
         || filter.Substring(0, 3) == r.Name.Substring(3, 3).ToLower() 
        select b); 

Après quelques tripoter, je suis les bâtiments distincts avec ce:

 public static Func<DataContext, string, IQueryable<Building>> 
      GearFilteredBuildings = 
       CompiledQuery.Compile((DataContext db, string filter) => 
        (from b in db.Building 
        join r in db.Router on b equals r.Building 
        orderby !b.Active 
        where filter.Length == 5 && r.Name.Substring(1, 5).ToLower() == filter 
         || filter.Substring(0, 3) == r.Name.Substring(3, 3).ToLower() 
        group b by b.Id into g 
         select g) as IQueryable<Building>); 

Est-ce une solution acceptable? Sinon, comment cela pourrait-il être fait?

+0

Si vous adhérez, vous verrez la duplication des lignes de parents en cas de plusieurs lignes enfants. C'est juste comment fonctionne la jointure. Ce n'est pas "étrange" du tout. –

Répondre

2

Je ne sais pas (ne pouvait pas tester IDE) mais select...join...lalala peut remplacer par la syntaxe LINQ-chaîne:

db.Routers 
    .Where(r => filter.Length == 5 && r.Name.Substring(1, 5).ToLower() == filter || filter.Substring(0, 3) == r.Name.Substring(3, 3).ToLower()) 
    .GroupBy(r => r.Building) 
    .Select(g => g.Key) 
    .OrderBy(b => !b.Active) 

aussi: que je ne vois pas join s sont vraiment requred dans votre requête, que vous avez propriétés de navigation (r.Building) dans votre modèle.

Ou une autre approche pourrait être utilisée, sélectionner tous les bâtiments nécessaires, et utiliser .Distinct() après:

db.Routers 
    .Where (r => filter.Length == 5 && r.Name.Substring(1, 5).ToLower() == filter || filter.Substring(0, 3) == r.Name.Substring(3, 3).ToLower()) 
    .Select(r => r.Building) 
    .Distinct() 
    .OrderBy(b => !b.Active) 
+0

La première suggestion a fonctionné. La deuxième suggestion n'a pas fonctionné car la méthode Distinct() n'a eu aucun effet sur l'ensemble de résultats. J'avais essayé (la déclaration linq) .Distinct() en vain aussi bien. J'ai également écrasé GetHashCodeMethod() de Building sans effet. Merci beaucoup pour la réponse. –

+0

et ici il est comme linq: de r dans db.Router où filter.Length == 5 && r.Name.Substring (1, 5) .ToLower() == filtre || filter.Substring (0, 3) == r.Name.Substring (3, 3) .ToLower() groupe r par r.Building dans grp select grp.Key –