2010-06-23 3 views
1

J'ai une collection (personnes) qui a une référence plusieurs-à-plusieurs à une autre collection (chiens). Suspendez votre incrédulité sur la façon dont il peut y avoir plus d'une personne par chien. Les gens contiennent juste un membre qui est List<Dog>Aide avec la requête linq. beaucoup à beaucoup

Je voudrais sélectionner toutes les personnes où les personnes ont une certaine propriété (spécifiée dans un IList) et les animaux domestiques ont une certaine propriété (spécifiée dans un IList).

E.g. J'ai un IList (utilisé pour cette requête seulement) avec la valeur de la propriété du chien.

public enum EnumLikesToBite 
{ 
No, 
Yes, 
Sometimes 
} 

IList <<EnumLikesToBite>> listDogsMayBite = 
{ { EnumLikesToBite.Yes}, 
{ EnumLikesToBite.Sometimes}}; 

Puis une autre liste pour la propriété des peuples:

public enum EnumKeepsPetWith 
{ 
Chain, 
String, 
Rubberband 
} 
IList <EnumKeepsPetWith> listPeopleWhoDontRestrainDog = 
{ { EnumKeepsPetWith.String }, 
{ EnumKeepsPetWith.Rubberband}}; 

Comment puis-je interroger toutes les personnes qui ont un chien qui peut mordre et ne pas retenir le chien. Comme ce code pseudo:

Var result = from p in People where p.KeepsPet in listPeopleWhoDontRestrainDog and dog.LikesToBite in listDogsMayBite. 

Le résultat a tout le peuple. Bien sûr, si je pouvais obtenir tous les chiens qui pourraient mordre sous ces gens, ce serait génial.

Répondre

1
List<int> mayBite = new List<int>() 
{ 
    (int) EnumLikesToBite.Yes, 
    (int) EnumLikesToBite.Maybe 
} 

List<int> poorRestraint = new List<int>() 
{ 
    (int) EnumKeepsPetWith.String, 
    (int) EnumKeepsPetWith.RubberBand 
} 

IQueryable<Person> query = 
    from p in db.People 
    where poorRestraint.Contains(p.KeepsPetWith) 
    where p.DogPeople.Any(dp => mayBite.Contains(dp.Dog.DoesBite)) 
    select p; 

var query = 
    from p in db.People 
    where poorRestraint.Contains(p.KeepsPetWith) 
    let bitingDogs = 
    from dp in p.DogPeople 
    let d = dp.Dog 
    where mayBite.Contains(d.DoesBite) 
    where bitingDogs.Any() 
    select new {Person = p, BitingDogs = bitingDogs.ToList()}; 
+0

impressionnant , comment fais-tu ça? Êtes-vous comme un surhumain ou quelque chose? – tim

0

Peut-être que ce code vous aidera .. Une des solutions possibles:

var result = 
     peoples.Where(y => dontRestrainDog.Contains(y.KeepsPetWith) && y.Dogs.Any(x => dogsMayBite.Contains(x.LikesToBite))).ToList(); 
    result.ForEach(y => y.Dogs = y.Dogs.Where(x => dogsMayBite.Contains(x.LikesToBite)).ToList()); 

que vous pouvez voir un exemple d'ici:

class Program 
    { 
     static void Main(string[] args) 
     { 
      IList<EnumLikesToBite> dogsMayBite = new List<EnumLikesToBite> 
                { 
                 { EnumLikesToBite.Yes }, { EnumLikesToBite.Sometimes } 
                }; 
      IList<EnumKeepsPetWith> dontRestrainDog = new List<EnumKeepsPetWith> 
                  { 
                   { EnumKeepsPetWith.String }, { EnumKeepsPetWith.Rubberband } 
                  }; 

      var peoples = new List<People>(); 
      var dogs = new List<Dog>(); 
      Random gen = new Random(2); 

      for(int i = 0; i < 10; i++) 
      { 
       People p = new People 
           { 
            PeopleId = i, 
            KeepsPetWith = (EnumKeepsPetWith) (gen.Next(10)%3), 
            Dogs = new List<Dog>() 
       }; 
       Dog d = new Dog 
          { 
           DogId = i, 
           LikesToBite = (EnumLikesToBite) (gen.Next(10)%3), 
           Peoples = new List<People>() 
          }; 
       peoples.Add(p); 
       dogs.Add(d); 
      } 
      for(int i = 0; i < 10; i++) 
      { 
       for(int j = 0; j < 10; j++) 
       { 
        if (gen.Next(10)>7) 
        { 
         peoples[i].Dogs.Add(dogs[j]); 
        } 
        if (gen.Next(10)>7) 
        { 
         dogs[i].Peoples.Add(peoples[j]); 
        } 
       } 
      } 
      PrintDogs(dogs); 
      PrintPeoples(peoples); 

      var result = 
       peoples.Where(y => dontRestrainDog.Contains(y.KeepsPetWith) && y.Dogs.Any(x => dogsMayBite.Contains(x.LikesToBite))).ToList(); 
      result.ForEach(y => y.Dogs = y.Dogs.Where(x => dogsMayBite.Contains(x.LikesToBite)).ToList()); 

      Console.WriteLine("==================="); 
      PrintPeoples(result); 
      Console.ReadLine(); 
     } 

     private static void PrintPeoples(List<People> peoples) 
     { 
      Console.WriteLine("=Peoples="); 
      foreach (var people in peoples) 
      { 
       Console.WriteLine("Id: {0}", people.PeopleId); 
       Console.WriteLine("KeepsPetWith: {0}", people.KeepsPetWith); 
       Console.WriteLine("Dogs: "); 
       foreach (var dog in people.Dogs) 
       { 
        Console.Write("{0}, ", dog.DogId); 
       } 
       Console.WriteLine(); 
      } 
     } 

     private static void PrintDogs(List<Dog> dogs) 
     { 
      Console.WriteLine("=Dogs="); 
      foreach (var dog in dogs) 
      { 
       Console.WriteLine("Id: {0}", dog.DogId); 
       Console.WriteLine("LikesToBite: {0}", dog.LikesToBite); 
       Console.WriteLine("Peoples: "); 
       foreach (var people in dog.Peoples) 
       { 
        Console.Write("{0}, ", people.PeopleId); 
       } 
       Console.WriteLine(); 
      } 
     } 
    } 

    public class People 
    { 
     public int PeopleId { get; set; } 
     public EnumKeepsPetWith KeepsPetWith { get; set; } 
     public IList<Dog> Dogs { get; set; } 
    } 

    public class Dog 
    { 
     public int DogId { get; set; } 
     public EnumLikesToBite LikesToBite { get; set; } 
     public IList<People> Peoples { get; set; } 
    } 

    public enum EnumLikesToBite 
    { 
     No, 
     Yes, 
     Sometimes 
    } 

    public enum EnumKeepsPetWith 
    { 
     Chain, 
     String, 
     Rubberband 
    } 
Questions connexes