2009-12-09 5 views
2

Je suis nouveau à LINQ alors excuses si c'est une réponse simple. Je suis en train de faire une JOIN SQL et ai le code suivant à partir d'exemples que j'ai vu sur le SO et ailleurs:LINQ à SQL Join

var query = from e in db.Events 
    join ec in db.EventCategories on e.ID equals ec.EventID 
    join c in db.Categories on ec.CategoryCode equals c.CategoryCode 
    join ep in db.EventParticipants on e.ID equals ep.EventID 
    join p in db.Participants on ep.ParticipantCode equals p.ParticipantCode 
    select new { e, ec, c, ep, p }; 

Cette exécute bien et quand je lance le débogueur je peux développer l'objet et de voir que la requête a été exécutée avec succès. Cependant, lorsque j'essaie d'exécuter query.ToList(), je ne peux pas convertir ceci en quelque chose d'utilisable car il indique que la liste retournée par query.ToList() est System.Collections.Generic.List.

Méthode 2: Sur la base de mes propres pensées, j'ai essayé de créer la structure suivante:

public struct CalendarItem 
    { 
     public Event e; 
     public EventCategory ec; 
     public Category c; 
     public EventParticipant ep; 
     public Participant p; 

     public CalendarItem(Event E, EventCategory EC, Category C, EventParticipant EP, Participant P) 
     { 
      e = E; 
      ec = EC; 
      c = C; 
      ep = EP; 
      p = P; 
     } 
    } 

et modifier ensuite la commande LINQ à ce qui suit:

var query = from e in db.Events 
    join ec in db.EventCategories on e.ID equals ec.EventID 
    join c in db.Categories on ec.CategoryCode equals c.CategoryCode 
    join ep in db.EventParticipants on e.ID equals ep.EventID 
    join p in db.Participants on ep.ParticipantCode equals p.ParticipantCode 
    select new CalendarItem(e, ec, c, ep, p); 

Dans Visual Studio ce contrôle out et ça me permet de compiler et tout a l'air génial (ie je peux boucler sur la liste de CalendarItems), mais j'ai une erreur d'exécution sur query.ToList(): Le membre 'e' n'a pas de traduction en SQL.

Répondre

4

Je fais mon CalandarItem une classe avec des propriétés automatiques:

public class CalendarItem 
{ 
     public Event E{get;set;} 
     public EventCategory EC{get;set;} 
     public Category C{get;set;} 
     public EventParticipant EP{get;set;} 
     public Participant P{get;set;} 
} 

et utilisation un initialiseur d'objet sur la sélection:

var query = from e in db.Events 
    join ec in db.EventCategories on e.ID equals ec.EventID 
    join c in db.Categories on ec.CategoryCode equals c.CategoryCode 
    join ep in db.EventParticipants on e.ID equals ep.EventID 
    join p in db.Participants on ep.ParticipantCode equals p.ParticipantCode 
    select new CalendarItem{E=e, EC=ec, C=c, EP=ep, P=p}; 

Je sais que cela fonctionne parce que je viens d'écrire un est arrivé peu similaire code il y a environ 2 minutes!

+0

Merci! Cela a fonctionné parfaitement – Kyle

1

Une option est d'appeler AsEnumerable après la projection anonyme:

var query = (from e in db.Events 
    join ec in db.EventCategories on e.ID equals ec.EventID 
    join c in db.Categories on ec.CategoryCode equals c.CategoryCode 
    join ep in db.EventParticipants on e.ID equals ep.EventID 
    join p in db.Participants on ep.ParticipantCode equals p.ParticipantCode 
    select new { e, ec, c, ep, p }) 
    .AsEnumerable() // Do the rest in process 
    .Select(x => new CalendarItem(x.e, x.ec, x.c, x.ep, x.p) 
    .ToList(); 

Par ailleurs, si vous êtes allez prendre cette approche, je conseille vivement contre l'utilisation d'une struct mutable, ou public des champs. Les deux sont des zones potentielles de problèmes. Vous pouvez facilement transformer en une classe immuable avec des propriétés, et en tout cas leur donner des noms utilisables :)

public class CalendarItem 
{ 
    public Event Event { get; private set; } 
    public EventCategory EventCategory { get; private set; } 
    public Category Category { get; private set; } 
    public EventParticipant EventParticipant { get; private set; } 
    public Participant Participant { get; private set; } 

    public CalendarItem(Event event, 
         EventCategory eventCategory, 
         Category category, 
         EventParticipant eventParticipant, 
         Participant participant) 
    { 
     Event = event; 
     EventCategory = eventCategory; 
     Category = category; 
     EventParticipant = eventParticipant; 
     Participant = participant; 
    } 
} 
+0

Je pense que cela aurait bien fonctionné, mais la façon dont je faisais le reste de mon code LINQ (c'est-à-dire conditionnel), la syntaxe ne semblait pas fonctionner. – Kyle