2010-06-26 4 views
1

Editer: Les deux réponses ci-dessous fonctionnent. Mon problème était dû à l'aide du fournisseur NHibernate LINQ comme ceci:Plusieurs requêtes LINQ "IN"

from parks in Session.Linq<Park>() 

au lieu de comme ceci:

from parks in Session.Linq<Park().AsEnumerable() 

J'ai une classe appelée parc qui a une des commodités. Je veux créer une requête LINQ qui retourne tous les objets Park qui contiennent chaque Amenity dans une liste. Donc, étant donné:

List<Park> Parks(IList<Amenity> amenities) 
{ 
    // I want a query that would look like this (if this worked) 
    // return all Park objects that have all of the given amenities 

    var query = from parks in db.Parks 
       where parks.Amenities.Contains(amenities) 
       select parks; 
} 

Cette requête:

var query = from parks in Session.Linq<Park>() 
    where amenities.All(a => parks.Amenities.Contains(a)) 
    select parks; 

ne fonctionne pas.

Voici plus de mon code pour le contexte:

classes de cartographie (I "m avec Fluent NHibernate)

public ParkDBMap() 
{ 
Id(x => x.ParkId).Column("ParkId").GeneratedBy.HiLo("0").UnsavedValue(0); 
Map(x => x.Name, "Name"); 
this.HasManyToMany<Amenity>(x => x.Amenities) 
.Table("ParksMaps_ParkAmenities") 
.Cascade.SaveUpdate(); 
} 


public AmenityDBMap() 
{ 
Id(x => x.AmenityId).Column("AmenityId").GeneratedBy.HiLo("0").UnsavedValue(0); 
Map(x => x.Name, "Name"); 
} 

Méthode d'essai:.

public void ListParksByAmenity() 
{ 
// Create Parks 
int parkCount = 10; 
CreateParks(parkCount); 

// Create Amenities 
Amenity restrooms = new Amenity(); 
restrooms.Name = "Restrooms"; 
ParksRepos.SaveAmenity(restrooms); 

Amenity tennis = new Amenity(); 
tennis.Name = "Tennis Courts"; 
ParksRepos.SaveAmenity(tennis); 

Amenity dogs = new Amenity(); 
dogs.Name = "Dogs Allowed"; 
ParksRepos.SaveAmenity(dogs); 

// Add amenities to parks 
IList<Park> parks = ParksRepos.Parks(); 

parks[0].AddAmenity(dogs); 
parks[0].AddAmenity(tennis); 
parks[0].AddAmenity(restrooms); 
ParksRepos.SavePark(parks[0]); 

parks[4].AddAmenity(tennis); 
parks[4].AddAmenity(restrooms); 
ParksRepos.SavePark(parks[4]); 

parks[9].AddAmenity(restrooms); 
ParksRepos.SavePark(parks[4]); 

IList<Amenity> amenityList = new List<Amenity>() { restrooms}; 
List<Park> restroomsParks = ParksRepos.Parks(amenityList); 

// three parks have restrooms 
Assert.AreEqual(1, restroomsParks.Count); 
Assert.AreEqual(parks[0].Name, restroomsParks[0].Name); 

amenityList = new List<Amenity>() { dogs, tennis, restrooms }; 
List<Park> allAmenities = ParksRepos.Parks(amenityList); 

// only one park has all three amenities 
Assert.AreEqual(3, allAmenities.Count); 

} 

J'ai trois tableaux A" Parks "table, une table" Amenities ", et une table many-to-many qui a deux colonnes, un ID de parc et un agrément ID

J'ai de la difficulté à envelopper ma tête. Quelqu'un a des suggestions?

Répondre

2
List<Park> Parks(IList<Amenity> amenities) 
{ 
    var query = from parks in db.Parks 
       where amenities.All(a => parks.Amenities.Where(sa => sa.ID == a.ID).Count() == 1) 
       select parks; 
} 
+0

Je pense que cela aurait fonctionné si je ne l'avais pas fait une faute de frappe dans ma question. La classe Park a une propriété List appelée Amenities, et non une propriété Amenity du même nom. Ma faute. – Jason

+0

Cela fonctionne réellement lorsque je spécifie "Count()" au lieu de "Count" à la fin. Cela n'a fonctionné qu'après avoir modifié mon code. J'utilisais NHibernate et LINQ avait: des parcs à Session.Linq () si j'utilise: Liste AllParks = this.Parks() puis: des parcs dans tous les parcs. .. reste de la requête cela fonctionne. – Jason

+0

désolé, j'ai oublié les accolades. – Femaref

1

Cela fonctionnera. Il retournera un IEnumerable. Pour convertir à la liste, vous devez faire un ToList() Remarque Je suppose que Park.Amenity est une liste

var x = from Park p in db.Parks where amenities.Except(p.Amenity).Count() == 0 select p; 
+0

Park.Amenities est une liste. Cette requête renvoie 0 lignes, cependant. – Jason

+0

Ensuite, aucun parc dans votre collection de Parcs contient une liste d'agréments qui a chaque commodité énumérée dans la collection d'agréments - ou il y a un malentendu. Postez votre code. – josephj1989

+0

Cela fonctionne lorsque je n'utilise pas le fournisseur NHibernate LINQ. Je dois faire deux requêtes ... tirer tous les parcs de la DB, puis les filtrer. Je ne suis pas sûr de la différence. – Jason