3

この質問は、以下の 2 つのアプローチのどちらがより推奨されているか (およびその理由は何か) を尋ねています。

C# 4.0 を使用して ServiceStack REST アプリケーションで FluentNHibernate を使用していますが、この質問は NHibernate LINQ クエリに一般的です。

次のことがより奨励されますか?

(方法 1)ユーザーの ID と一致するすべての行を返す単純なクエリをすばやく実行します。

// Query the User by id
var user = session.Get<User>(request.UserId);

次に、返されたリストで LINQ を個別に使用して、結果をさらに絞り込みます。

// 'User' contains a 'List<Location>'
var locations = user.Locations.Where(location =>
                        location.Timestamp >= (request.MinTimestamp.HasValue ? request.MinTimestamp.Value : 0) &&
                        location.Timestamp <= (request.MaxTimestamp.HasValue ? request.MaxTimestamp.Value : DateTime.Now.ToTimestamp()));

return locations;

(方法 2) または、単一のクエリで上記を実行するより複雑なクエリを実行することをお勧めします。

var locationsQuery = session.QueryOver<LocationModel>()
                        .Where(table => table.User.Id == request.UserId)
                        .And(table => table.Timestamp >= (request.MinTimestamp.HasValue ? request.MinTimestamp.Value : 0))
                        .And(table => table.Timestamp <= (request.MaxTimestamp.HasValue ? request.MaxTimestamp.Value : DateTime.Now.ToTimestamp()));

return locationsQuery.List();

私の目標が次の場合:

a) 実行時間の短縮


ベンチマーク(改訂版)

改訂された完全なテスト コード: http://pastebin.com/0ykKwcxX

ベンチマーク出力:

方法 1は、5000 回の反復で147.291 秒かかりました。

最後のイテレーションのクエリ結果:
{Timestamp = 1348659703485、Latitude = 179.40000、経度= 209.40000}
{Timestamp = 1348659703486、Latitude =
179.55000、経度= 209.55000}
{Timestamp = 13487034887088708870890 = 17487000 、緯度 = 179.85000、経度 = 209.85000 }
{ タイムスタンプ = 1348659703489、緯度 = 180.00000、経度 = 210.00000 }

方法 2は、5000 回の繰り返しで133.728 秒かかりました。

最後のイテレーションのクエリ結果:
{Timestamp = 1348659703485、Latitude = 179.40000、経度= 209.40000}
{Timestamp = 1348659703486、Latitude =
179.55000、経度= 209.55000}
{Timestamp = 13487034887088708870890 = 17487000 、緯度 = 179.85000、経度 = 209.85000 }
{ タイムスタンプ = 1348659703489、緯度 = 180.00000、経度 = 210.00000 }

違い: 方法 2 は約 13.5 秒高速でした。


b) 長期的な再利用と安定性

4

1 に答える 1

1

あなたの目標が実行時間を短縮することである場合、User エンティティの不要な読み込みを行わないため、2 番目のアプローチが最適であると考えていました。そうは言っても、私はNHibernateのユーザーではないので、確かなことはわかりません. - 誰が言ったか思い出せませんが、かなり良い格言です)。

Ayende は、見る価値のある NHibernate の優れた投稿をたくさん書いています (例: http://ayende.com/blog/3988/nhibernate-the-difference-between-get-load-and-querying-by-id )

「長期的な再利用と安定性」に関しては、この種のコードをどのように使用しているかによって異なります。ユーザー ID フィルターとタイムスタンプ フィルターが拡張メソッドになるように、クエリ部分をいつでもリファクタリングできます。例については、この投稿を参照してください: http://lostechies.com/jimmybogard/2012/08/30/evolutionary-project-structure/

于 2012-09-25T07:54:57.103 に答える