のそれぞれをソートする:私はすべてのコンピュータを問い合わせる場合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が私の結合が子供をフェッチすることを意図していたとは思わないと思う。
問題は、どうすれば2番目のクエリを制御できますか?たとえば、メーカーの名前でデバイスを注文する場合、または各Computer.Devices
のリストに、IBMが作成したデバイス(存在する場合)のみが含まれるようにします。私はそのためにサブクエリが必要だと思いますが、どこにプラグインしますか?
ただ、完全を期すために、ここに私の設定です:
class ExampleConfig : DefaultAutomappingConfiguration
{
public override bool ShouldMap(Type type)
{
return type.Namespace == "TryHibernate.Example";
}
}
"何かを注文するにはあまりにも多くの仕事があるようですが、SQLはすぐに使えるものです" - 全く同意します。それは簡単ではありませんが、そうではありません。 NHibernateは、しばしば、成熟していると同時に愚かな能力を持っています。ドキュメンテーションの質はもちろんですが... NHではLINQのサポートがあります。あなたはそれを見たことがありますか? –
@Bozhidar、右、私はLinqを見たことがありますが、この場合に使用できるかどうかは不明ですし、SQLにマップするのか、メモリ内での並べ替えなのか分かりません。フェッチされたコレクションではいつでも自分自身で行うことができるからです。 –