2012-05-13 2 views
19

include matchparticipants non funziona. Dice sempre Null quando eseguo il debug. Ma quando inserisco il GroupBy nel commento, funziona bene. Sto usando Entity framework 4.3.1 con code-first.Linq quando si utilizza GroupBy, Includi non funziona

Entità:

public class Match 
    { 
     [ScaffoldColumn(false)] 
     public int MatchId { get; set; } 

     [Required(ErrorMessage = "Matchtype is a required field")] 
     public int Scheme { get; set; } 

     [Required] 
     [DefaultValue(false)] 
     public bool Finished { get; set; } 

     public int Round { get; set; } 


     // Relations 
     [Required] 
     public Category Category { get; set; } 

     public Official Official { get; set; } 

     public Slot Slot { get; set; } 

     public ICollection<MatchParticipant> MatchParticipants { get; set; } 
    } 

public class MatchParticipant 
    { 
     [ScaffoldColumn(false)] 
     public int MatchParticipantId { get; set; } 

     public int Points { get; set; } 

     public int Goals { get; set; } 

     [Required] 
     public Match Match { get; set; } 

     [Required] 
     public Team Team { get; set; } 
    } 

public class Team 
    { 
     [ScaffoldColumn(false)] 
     public int TeamId { get; set; } 

     [Required(ErrorMessage="Name is a required field")] 
     public string Name { get; set; } 

     [Required(ErrorMessage="Number of players is a required field")] 
     public int NumberOfPlayers { get; set; } 

     [Required(ErrorMessage="Coach is a required field")] 
     public string Coach { get; set; } 

     [Required(ErrorMessage="Phone is a required field")] 
     public string Phone { get; set; } 

     public string CellPhone { get; set; } 

     public string Fax { get; set; } 

     [Required(ErrorMessage="Email is a required field")] 
     public string Email { get; set; } 

     [Required(ErrorMessage="Address is a required field")] 
     public Address Address { get; set; } 

     public Pool Pool { get; set; } 

     [Required(ErrorMessage = "Category is a required field")] 
     public Category Category { get; set; } 

     public ICollection<MatchParticipant> matchParticipants { get; set; } 
    } 

     var matches = 
     context.matches 
     .Include("Official") 
     .Include("Slot") 
     .Include("MatchParticipants.Team") 
     .Include("Category.Tournament") 
     .Where(m => m.Category.Tournament.TournamentId == tournamentId) 
     .GroupBy(m => m.Category); 

Come posso fare il lavoro include?

risposta

38

Include richiede che la forma della query non cambi. Significa che la tua query deve restituire IQueryable<Match>. L'operatore GroupBy viene probabilmente considerato come un cambio di forma poiché restituisce IQueryable<IGrouping<TKey, TSource>>. Una volta che la forma della query cambia, tutte le istruzioni Includi vengono omesse. Per questo motivo non è possibile utilizzare Include con proiezioni, join e raggruppamenti personalizzati.

Come soluzione alternativa è possibile eseguire il raggruppamento in LINQ-to-oggetti:

var matches = context.matches 
        .Include("Official") 
        .Include("Slot") 
        .Include("MatchParticipants.Team") 
        .Include("Category.Tournament") 
        .Where(m => m.Category.Tournament.TournamentId == tournamentId) 
        .ToList() 
        .GroupBy(m => m.Category); 
+1

Grazie amico funziona ora :) – Bart

+3

Eventuali ulteriori suggerimenti per quando è necessario mantenere il tipo di oggetto come IQueryable <>? –

18

In questo caso particolare, quando il GroupBy è l'ultimo operatore, questa query funziona bene ... Ma secondo me risposta di cui sopra è la risposta peggiore per il principiante, perché la causa una query ottimizzata veramente male quando il tuo GroupBy non viene eseguito subito dopo, ma è seguito da qualche altra istruzione (Dove, Seleziona ...).

var ctx = new MyDataContext(); // Please use "using" 
var result = ctx.SomeTable 
       //.Include(ah => ah.IncludedTable) // DO NOT PUT IT HERE 
       .Where(t => t.IsWhateverTrue) 
       .GroupBy(t => t.MyGroupingKey) 
       .Select(gt => 
        gt.OrderByDescending(d => d.SomeProperty) 
         .FirstOrDefault(ah => ah.SomeAnotherFilter)) 
       .Include(ah => ah.IncludedTable) // YES, PUT IT HERE 
       .ToList(); // Execute query here 
+0

Questo non viene compilato, IEnumerable non contiene una definizione per Include – Smithy

+3

Non dimenticare: using System.Data.Entity; – Tomino

+1

Posso confermare che questo approccio funziona; cioè mettendo l'inclusione alla fine della query. Si noti che potrebbe essere necessario aggiungere un Distinct prima dell'inserimento. –