2013-08-21 4 views
2

J'ai donc ci-dessous des requêtes. Je voudrais vraiment les fusionner en 1 requête. À côté du fait qu'il en résulte une collection vide (ce qui ne devrait pas) Mon cerveau a juste implosé quand j'ai essayé de faire ceci en 1 requête.Comment puis-je fusionner ces requêtes en 1

Donc, si ce n'est pas clair à partir du code je veux sélectionner tous les chevaux d'un certain utilisateur. qui n'ont pas été inscrits pour la course pour laquelle l'utilisateur essaie de s'inscrire.

var userhorses = (from h in entities.Horses 
          where h.UserId == id 
          select h); 

var race = (from r in entities.Races 
        where r.Id == id 
        select r).Single(); 

var runninghorses = (from rh in race.RacingHorses 
        where rh.UserId == id 
        select rh); 

var nonracinghorses = (from nrh in userhorses 
         from rh in runninghorses 
         where nrh.Id != rh.Id 
         select nrh).ToList(); 

EDIT

public class Horse 
{ 
    [Key] 
    public int Id { get; set; } 

    public int? UserId { get; set; } 
    public virtual User Owner { get; set; } 

    [Required(ErrorMessage = "Name is required")] 
    public string Name { get; set; } 
    public int? GenderId { get; set; } 
    public virtual Gender Gender { get; set; } 
    public int? ColorId { get; set; } 
    public virtual Color Color { get; set; } 
    public int? LegTypeId { get; set; } 
    public virtual LegType LegType { get; set; } 
    public int? CharacterId { get; set; } 
    public virtual Character Character { get; set; } 
    public int Hearts { get; set; } 
    public bool Retired { get; set; } 
    public bool CPU { get; set; } 
    public bool ForSale { get; set; } 
    public int ListPrice { get; set; } 
    public DateTime? Deadline { get; set; } 
    // Parents 
    public int? SireId { get; set; } 
    public virtual Horse Sire { get; set; } 
    public int? DamId { get; set; } 
    public virtual Horse Dam { get; set; } 
    // Internals 
    public int Stamina { get; set; } 
    public int Speed { get; set; } 
    public int Sharp { get; set; } 
    // Special 
    public int Dirt { get; set; } 
    // Externals 
    public int Start { get; set; } 
    public int Corner { get; set; } 
    public int OutOfTheBox { get; set; } 
    public int Competing { get; set; } 
    public int Tenacious { get; set; } 
    public int Spurt { get; set; } 
    //Future 
    public virtual ICollection<Race> FutureRaces { get; set; } 
    //RaceResults 
    public virtual ICollection<RaceResult> RaceResults { get; set; } 
    //Training 
    public virtual ICollection<Training> TrainingResults { get; set; } 
    //Bids 
    public virtual ICollection<Bid> Bids { get; set; } 

    public Horse() { 
     ForSale = false; //default value 
     Deadline = null; 
    } 
} 


public class Race 
{ 
    [Key] 
    public int Id { get; set; } 
    [Required(ErrorMessage = "Name is required")] 
    public string Name { get; set; } 
    [Required(ErrorMessage = "Purse is required")] 
    public int Purse { get; set; } 
    [Required(ErrorMessage = "Slots are required")] 
    public int Slots { get; set; } 
    public int SlotPrice { get; set; } 
    public DateTime? RaceTime { get; set; } 

    //public int? TrackId { get; set; } 
    //public virtual Track Track { get; set; } 

    public int? OwnerId { get; set; } 
    public virtual User Owner { get; set; } 

    public virtual ICollection<Horse> RacingHorses { get; set; } 

    public virtual ICollection<RaceResult> RaceResults { get; set; } 

    public Race() 
    { 
     SlotPrice = 0; //default value 
     Slots = 8; 


    } 


} 
+1

D'abord, faites-le réussir, inefficacement si nécessaire. –

+0

n'essayant pas de le faire échouer plus avec succès. en plus de la réparer, je veux le réparer de la bonne façon. – Puzzle84

+0

Ne vous inquiétez pas de le rendre plus rapide jusqu'à ce que vous l'ayez fait correctement. C'est ce qu'on appelle "l'optimisation prématurée". –

Répondre

0

tous les kudo vont à nmclean pour celui-ci. Pourquoi essaieriez-vous de faire échouer votre code plus efficacement?

public static SelectList GetNonRacingHorses(int id, int raceId) 
{ 
    HorseTracker entities = new HorseTracker(); 

    var race = entities.Races.Single(r => r.Id == raceId); 
    var racehorses = from h in race.RacingHorses 
        select h.Id; 

    var userhorses = (from h in entities.Horses 
         where 
          h.UserId == id 
         orderby h.Name 
         select h); 

    var nonracinghorses = from h in userhorses 
          where !racehorses.Contains(h.Id) 
         select h; 

    List<SelectListItem> sli = new List<SelectListItem>(); 

    foreach (Horse horse in nonracinghorses) 
    { 
     sli.Add(new SelectListItem { Text = horse.Name, Value = horse.Id.ToString(), Selected = false}); 
    } 

    return new SelectList(sli, "Value", "Text"); 
} 
0

Avez-vous pensé à utiliser le mot-clé "nous"?

http://msdn.microsoft.com/en-us/library/bb383976.aspx

Il semble aussi que vous pourriez prendre avantage de la « sauf » fonctionnalité

http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

(Comme je n'ai pas la réputation de faire un commentaire, pourquoi vous réutilisez la variable "id" pour l'utilisateur et l'identification d'une course?)

Une suggestion supplémentaire est que vous pouvez filtrer à l'intérieur de l'unique

var race = entities.Races.Single(r => r.Id == raceId); 
+0

Je n'avais pas, je ne savais pas qu'il existait en regardant ça maintenant. – Puzzle84

+0

Bonne prise. Parfois, vous avez besoin de cette deuxième paire d'yeux. regarde ça maintenant. Ok ça ne l'a pas réparé parce que je suis en train de tester avec le 1er utilisateur que je n'ai pas attrapé plus tôt: D. lookinf at laisser maintenant – Puzzle84

0

Je fais ces hypothèses:

  • vous avez id, l'ID utilisateur
  • vous avez raceId, l'ID de la course en cours de signature pour
  • il y a une collection entities.RacingHorses qui est les associations d'identification de race et de cheval

Ensuite, vous pouvez utiliser:

from h in entities.Horses 
where h.UserId == id 
let rhs = entities.RacingHorses.Where(rh => rh.HorseId == h.Id) 
where !rhs.Any(rh => rh.RaceId == raceId) 
select h 

Répartition:

  • h = si raceId apparaît dans rhs un cheval de l'utilisateur
  • rhs = associations RacingHorses pour h
  • , puis h est signé pour cette course; ne sélectionnez pas ceci h
+0

Cela est très correctement supposé: D test maintenant: D En fait des changements mineurs là-bas. chaque course a une collection racinghorses. Je n'ai pas d'entité pour les chevaux de course mais pour la course – Puzzle84

+0

@ Puzzle84 Si une course a une collection de chevaux, un cheval a-t-il aussi une collection de courses (ou un RaceID)? – nmclean

+0

Non. Cheval a un identifiant La race a un identifiant. Race a une collection d'identifiants de chevaux. Peut-être que je devrais ajouter cela au cheval pour contourner cette situation – Puzzle84