2009-06-03 9 views
1

私は最も速い方法を探していますオブジェクトの存在を確認。 このシナリオは非常に簡単です。ディレクトリツールを想定して、現在のハードドライブを読み取ります。ディレクトリが見つかった場合は、ディレクトリを作成するか、存在する場合は更新する必要があります。これはに関して移動するための方法ですNHibernateのオブジェクトの存在を問い合わせる最速の方法

public static DatabaseDirectory Get(DirectoryInfo dI) 
    { 
     var result = DatabaseController.Session 
         .CreateCriteria(typeof (DatabaseDirectory)) 
         .Add(Restrictions.Eq("FullName", dI.FullName)) 
         .List<DatabaseDirectory>().FirstOrDefault(); 

     if (result == null) 
     { 
      result = new DatabaseDirectory 
         { 
          CreationTime = dI.CreationTime, 
          Existing = dI.Exists, 
          Extension = dI.Extension, 
          FullName = dI.FullName, 
          LastAccessTime = dI.LastAccessTime, 
          LastWriteTime = dI.LastWriteTime, 
          Name = dI.Name 
         }; 
     } 
     return result; 
    } 

まず作成部にのみ焦点をすることができます

  • スピード
  • 関心の分離は

何になります心は以下の通りです。スキャンは常に「全体として」実行されます。つまり、ドライブCのスキャン中に、(何か他のプロセスから)新しいものがデータベースに追加されないことがわかります。ですから、スキャンの前にすべての既存のディレクトリを "キャッシュ"して、このように調べることをお勧めします。一方、これはファイル(600.000以上になります)のような大きなデータセットには適していないかもしれません...

「インデックス列」などを使用するとパフォーマンスが向上する可能性がありますが、私はこの話題にあまり慣れていません。誰もがいくつかの参照を持っている場合は、単に

おかげで、 クリス

PSが...正しい方向に私を指す:私はNHibernateは、流暢インタフェース、自動マッピングおよびSQL Expressを使用していますが(完全なSQLに切り替えることができ)

注: この問題では、パスはデータベース内のIDではありません。 IDは自動インクリメントで、この要件を変更することはできません(その他の理由)。だから、本当の問題は、への最速の方法は何です

や調剤の「IDが知られていないオブジェクトのexistance、そのオブジェクトのプロパティだけをチェックする」を選択することにより、可能であるかもしれません"C:Testfilesで始まる"というような大きなグループではあるが、問題は残っている。このセットがどのくらい大きくなるのかを事前に知る方法を知っている。私は "最大1000"を選択することはできませんし、私は "検索されたディレクトリの隣にヒット"かもしれないので、このバッファに入れられた辞書をチェック...私はこの問題がはっきりしていることを願っています。最も重要な部分は、バッファリングが実際にパフォーマンスに大きな影響を与えていることです。そうであれば、PATHとIDだけを含む辞書にDB全体をロードするのは意味がありますか?(それは1.000.000のオブジェクトがあってもOKです。)

答えて

2

最初に、私は非常にあなたは(NHを使っている人は誰でも)differences between Get, Load, and queryに関するAyendeの記事を読むことをお勧めします。

存在を確認する必要があるため、オブジェクトを選択するクエリの代わりに.Get(id)を使用します。

しかし、問題のドメインの知識を活用してパフォーマンスを向上させることができるかどうかは疑問です。ドライブ全体をスキャンし、各ディレクトリにデータベースが存在するかどうかを確認する場合は、一括操作を実行するとパフォーマンスが向上する可能性があります。おそらく、データ転送/処理をさらに最小限に抑えるために、DatabaseDirectoryオブジェクトのPKだけを含むDTOオブジェクトを作成してください。ような何か:

Dictionary<string, DirectoryInfo> directories; 
session.CreateQuery("select new DatabaseDirectoryDTO(dd.FullName) from DatabaseDirectory dd where dd.FullName in (:ids)") 
    .SetParameterList("ids", directories.Keys) 
    .List(); 

は、それからちょうど存在しないディレクトリを取得するために返されたID値に一致する要素を削除します。入力セットの大きさ(ほとんどの場合、ファイルの場合)に応じて、プロセスをより小さなバッチに分割する必要があります。

懸念事項を除いては、操作をリポジトリレベルに保つだけです。 SyncDirectoriesのような方法で、データベースを更新するプロセスを処理するコレクション(上記のような場合はDictionary)を取得します。そうすれば、より高いアプリケーション・ロジックは、それがどのように動作するか心配する必要はなく、将来的にそれを行うためのさらに高速な方法が見つかるはずです。

+0

ご回答ありがとうございます。バルク部分は面白いです、私はこれを詳細に調べなければなりません。最初の提案の問題:私はIDを知らない。パスはIDではありません。私はこれを上記のポストに追加してより明確にします。答えをありがとう... –

関連する問題