的考虑这个人为的域名: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还是进行内存排序,这是毫无意义的因为我总是可以自己在取回的集合上做到这一点。 –