的考慮這個人爲的域名:NHibernate的QueryOver排序每一個一對多的集合
namespace TryHibernate.Example {
public class Computer
{
public int Id { get; set; }
public IList<Device> Devices { get; set; }
}
public class Device
{
public int Id { get; set; }
public Maker Maker { get; set; }
}
public class Maker
{
public int Id { get; set; }
public string Name { get; set; }
}
} // namespace
如果我只是查詢所有計算機,他們的設備將被隨機排序。我想讓他們按製造商的名字訂購。我不能用HasMany().OrderBy()
這麼做,因爲據我所知OrderBy
只能使用本地列(所以我可以用Device.Id
來排序)。此外,它可以很好地控制每個查詢的順序,所以我正在尋找一個QueryOver
解決方案。
我能得到最遠的是這樣的:
using (ISessionFactory sessionFactory = Fluently.Configure()
.Database(SQLiteConfiguration.Standard.UsingFile("temp.sqlite").ShowSql())
.Mappings(m => m.AutoMappings.Add(
AutoMap.AssemblyOf<Computer>(new ExampleConfig())
.Conventions.Add(DefaultLazy.Never())
.Conventions.Add(DefaultCascade.All())))
.ExposeConfiguration(c => new SchemaExport(c).Create(true, true))
.BuildSessionFactory())
{
using (ISession db = sessionFactory.OpenSession())
{
Computer comp = new Computer();
comp.Devices = new List<Device>();
Device dev1 = new Device();
comp.Devices.Add(dev1);
dev1.Maker = new Maker() { Name = "IBM"};
Device dev2 = new Device();
comp.Devices.Add(dev2);
dev2.Maker = new Maker() { Name = "Acer"};
db.Persist(comp);
db.Flush();
}
using (ISession db = sessionFactory.OpenSession())
{ // This is the part I'm having trouble with:
Device devAlias = null;
Maker makerAlias = null;
IList<Computer> comps = db.QueryOver<Computer>()
.JoinAlias(c => c.Devices,() => devAlias)
.JoinAlias(() => devAlias.Maker,() => makerAlias)
.OrderBy(() => makerAlias.Name).Asc
.List();
Console.WriteLine(comps.Count);
foreach (Device dev in comps[0].Devices)
{
Console.WriteLine(dev.Maker.Name);
}
}
}
但是,當然,它不會做我想做的。它試圖按製造商的名稱對整個清單進行分類。它也成功了,正如我從SQL中看到的那樣,實際上我得到了一個無用的笛卡爾計算機產品,其中包含由設備製造商分類的設備。
但它然後發出另一個SQL查詢來獲取設備,這次沒有排序。我猜NHibernate不知道我的聯接是爲了取孩子。
問題是,我該如何控制第二個查詢?例如,要按製造商的名稱訂購設備,或者要讓每個Computer.Devices
列表僅包含由IBM(如果有)製造的設備。我想我需要一個子查詢,但我在哪裏插入?
只是爲了完整性,這裏是我的配置:
class ExampleConfig : DefaultAutomappingConfiguration
{
public override bool ShouldMap(Type type)
{
return type.Namespace == "TryHibernate.Example";
}
}
」看起來工作太多,只是爲了訂購一些東西,而SQL支持現成的「 - 完全同意。它應該更簡單,但事實並非如此。 NHibernate經常有這種能力,既成熟又愚蠢;同時,更不用說文檔質量......但NH中有LINQ支持。你見過嗎? –
@Bozhidar,對,我見過Linq,但我不確定它是否可以用在這種情況下,而且我不確定它是映射到SQL還是進行內存排序,這是毫無意義的因爲我總是可以自己在取回的集合上做到這一點。 –