私の問題をより簡単に説明するために、非常に基本的な多対多関係を示す次の架空の例を作成します。 車は多くのの部分、の部分は多くのの車に属することができます。Nhibernate QueryOver - 多対多関係のすべてを実行する
DBスキーマ:私は、リストからそれらに割り当てられたすべての部分を持っているすべての車を取得したいと思い、この非常に単純なモデルを使用して
public class Car
{
public int CarId {get;set;}
public string Name {get;set;}
public IEnumerable<Part> Parts {get;set;}
}
public class Part
{
public int PartId {get;set;}
public string Name {get;set}
}
:
CAR_TABLE
---------
CarId
ModelName
CAR_PARTS_TABLE
---------------
CarId
PartId
PARTS_TABLE
-----------
PartId
PartName
クラス私が探している部品の
だから私はPartIdsの配列を持っていると言う:
var partIds = new [] { 1, 3, 10};
私は、データベース・コールの点では、次のC#コードを模倣したい:明確にするため
var allCars = /* code to retrieve all cars */
var results = new List<Car>();
foreach (var car in allCars)
{
var containsAllParts = true;
foreach (var carPart in car.Parts)
{
if (false == partIds.Contains(carPart.PartId))
{
containsAllParts = false;
break;
}
}
if (containsAllParts)
{
results.Add(car);
}
}
return results;
を:私が取得したいですpartIds配列から指定されたすべてのPartsを持つCars。
次のクエリがあります。これは、partIds配列内の各idに対してサブクエリを作成し、それぞれの結果に対してIsInクエリを実行するため、本当に効率が悪いです。私は、このクエリを実行するためのはるかに効率的な方法を見つけることが切望されています。
Car carAlias = null;
Part partAlias = null;
var searchCriteria = session.QueryOver<Car>(() => carAlias);
foreach (var partId in partIds)
{
var carsWithPartCriteria = QueryOver.Of<Car>(() => carAlias)
.JoinAlias(() => carAlias.Parts,() => partAlias)
.Where(() => partAlias.PartId == partId)
.Select(Projections.Distinct(Projections.Id()));
searchCriteria = searchCriteria
.And(Subqueries.WhereProperty(() => carAlias.Id).In(carsWithPartCriteria));
}
var results = searchCriteria.List<Car>();
NHibernateを使用してこの種のクエリを実行する方法はありますか?
部品のコンテキストから開始するように、クエリー・パスを非常に巧妙に逆転させます。 :)私はこれを試し、あなたに知らせるでしょう。ありがとう。 – ctrlplusb
より効率的に、完璧に動作します。バツ – ctrlplusb