多对多LINQ“IN”查询

时间:2010-06-26 21:18:29

标签: asp.net linq

编辑:以下两个答案都有效。我的问题是由于使用NHibernate LINQ提供程序 像这样:

from parks in Session.Linq<Park>()

而不是像这样:

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

我有一个名为Park的课程,有一个设施。我想创建一个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;

不起作用。

以下是我的上下文代码:

映射类(我使用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");
}

测试方法:

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

}

我有三张桌子。一个“公园”表,一个“设施”表和一个多对多表,它有两列,一个公园ID和一个设施ID。

我无法绕过这个问题。有人有什么建议吗?

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:1)

这将有效。它将返回一个IEnumerable。要转换为List,您需要执行ToList() 注意我假设Park.Amenity是一个列表

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