2010-06-26 108 views
1

編輯:下面的答案都有效。我的問題是由於使用NHibernate的LINQ提供程序 這樣的:多對多LINQ「IN」查詢

from parks in Session.Linq<Park>() 

,而不是像這樣:

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

我有一個叫公園類,它有一個設施。我想創建一個LINQ查詢,它返回列表中包含每個Amenity的所有Park對象。因此,考慮:

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; 
} 

這個查詢:

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

不起作用。

這裏有更多的我的代碼上下文:

類映射(我 「米使用功能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"); 
} 

試驗方法:

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); 

} 

我有三個表A」公園「桌子,」便利設施「桌子,以及具有兩列,一個公園ID和一個設施ID的多對多桌子

我在纏繞這個問題時遇到了麻煩。任何人有任何建議?

回答

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

我想,如果我沒有在我的問題做了一個錯字這會工作。 公園班有一個列表屬性,稱爲設施,而不是同一個名稱的舒適屬性。我的錯。 – Jason 2010-06-26 22:10:15

+0

當我在最後指定「Count()」而不是「Count」時,這實際上起作用。不過,它只在修改我的代碼後才起作用。我使用NHibernate到LINQ和有: 從公園 在Session.Linq () 如果我使用: 列表 AllParks = this.Parks() ,然後:在所有的公園公園 。 ..其餘的查詢 它的工作原理。 – Jason 2010-06-26 22:58:28

+0

對不起,忘了大括號。 – Femaref 2010-06-26 23:08:27

1

這將工作。它將返回一個IEnumerable。要轉換到列表,你需要做一個ToList() 注意我假定Park.Amenity是一個列表

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

Park.Amenities是一個列表。不過,這個查詢返回0行。 – Jason 2010-06-26 22:11:07

+0

然後,您的公園收藏中沒有任何公園包含便利設施列表,每個設施都列有各種便利設施 - 或者存在誤解。加入您的代碼。 – josephj1989 2010-06-26 22:19:23

+0

這適用於我不使用NHibernate LINQ提供程序。我必須做兩個查詢...從數據庫中提取所有公園,然後過濾它們。我不確定有什麼不同。 – Jason 2010-06-26 23:01:23