2016-07-05 9 views
1

フィールド値を設定する各レコードで関数を呼び出そうとしています。結果はその後、ページングされることを意図している場合、これは次のように実現されます。ダッパー結果から各レコードの関数を呼び出す

public IDataWrapper GetPagedQuery<T>(string myQuery, object param, Action<T> customAction) 
{ 
    var obj = new DataWrapper(); 
    using (var oConn = CreateConnection(ConnectionString)) 
    { 
     TotalPages totalRows = null; 
     var list = oConn.Query<T, TotalPages, T>(myQuery, (e, t) => 
     { 
      totalRows = t; 
      if (mapAction != null) customAction(e); 
      return e; 
     }, param, splitOn: "SplitOn"); 
     obj.RowsFound = (IEnumerable<dynamic>)list; 
     obj.TotalRows = totalRows == null ? 0 : totalRows.TotalRows; 
    } 
    return obj; 
} 

私の問題は、結果がページングされることを意図していないときに来ています。最初の例の私のクエリにはsplit on columnが含まれているので、それはすべて正常に動作しますが、次のクエリはすべての行や列などを返すSelect Column1, Column2 FROM MyAwesomeTableなどの単純なクエリです。

問題は戻ってくる各結果に対してcustomActionを適用する必要があります。今度は数百万のレコードが潜在する可能性があることを想像してみてください。私の状況では、これは非現実的ではないと私に信じてください。最初のケースと同じように、ダッパーが結果を返すときに適用されます。ここで

は、私が試したものです:

public IDataWrapper GetNonPagedQuery<T>(string myQuery, object param, Action<T> customAction) 
{ 
    var obj = new DataWrapper(); 
    using (var oConn = CreateConnection(ConnectionString)) 
    { 
     var list = oConn.Query<T>(myQuery, (e) => 
     { 
      if (mapAction != null) customAction(e); 
      return e; 
     }, param).ToList(); 
     obj.RowsFound = (IEnumerable<dynamic>)list; 
     obj.TotalRows = list.Count(); 
    } 
    return obj; 
} 

私はそれが方法Query<T>(etc...私はそれが存在しないので、それがあることを理解し解決することはできません上記のコードのエラーを取得します。私はここで何をしようとしているのかを達成する最良の方法を尋ねています。それは大胆で可能ですか?

+0

SplitOnについてのあなたの理解は間違っています。その目的は、1-1複合エンティティをマップすることであり、ページネーションとは関係がなく、あらゆる種類のクエリで使用できます。 Sqlクエリとしてフェッチされた同じ繰り返し値となる、すべてのレコードのTotalRowsを置き換える現在のコードは、それ自体が最適な使用法ではありませんが、任意の数のレコードで他の部分についても繰り返すことができます。あなたが明示的に適用されている場合、メモリ内のデータを取得して、メモリ内のデータを行き来することを心配する必要はありません。 –

+0

@MrinalKamboj私はSplitOnをよく理解していると信じています。完全なSQL文。私は質問の中のその部分を誤解し、誤解を説明することができないかもしれません。私が言っていたのは、ページネーションはspliton列を使用しているということです。短いストーリー、最初のクエリはSplitOnを使用し、2番目のクエリは使用しません。誤解して申し訳ありません。 – Bojan

+0

私の言い方を理解すると、SplitOnにカスタムアクションを適用するために提供されたFuncを使用しています。実際にはSplitonでも繰り返し値を満たしていますが、どちらも正しくありません。 Dapperが実際にLinq 2のオブジェクトプロバイダであるようにメモリコレクションを通過しているときに、コレクションをトラバースする必要はないという印象の下にありました。理想的な方法は、どこでもSplitOnを削除することです。代わりにQueryMultipleを使用して、単一の呼び出しで別々の結果を取得し、受け入れた応答に示されているように個別にアクションを適用します –

答えて

1

私は、短い答えはあなたがこれをすることができないということです。

やや長めの答えはDapperのは「T」のインスタンスに各行のデータを変換するためのいくつかの作業を行い、それが別の呼び出しを行いますので、あなたのページングクエリで、それは本質的データを通る第2のパスであるということですあなたの "customAction"を呼び出すために使用する "map"メソッドに渡します。

したがって、単純な非ページング "conn.Query"コールの後にcustomActionを実行するための後続のパスが続くことにはほとんど違いがありません。以下のような何か:

public IDataWrapper GetNonPagedQuery<T>(string myQuery, object param, Action<T> customAction) 
{ 
    var obj = new DataWrapper(); 
    using (var oConn = CreateConnection(ConnectionString)) 
    { 
     var results = oConn 
      .Query<T>(myQuery) 
      .ToList(); 
     obj.TotalRows = results.Count(); 
     obj.RowsFound = results 
      .Select(value => 
      { 
       customAction(value); 
       return value; 
      }) 
      .Cast<dynamic>(); 
    } 
    return obj; 
} 

あなたの懸念は、あなたが非ページのクエリでは、多くの、多くのレコードをロードすることができるということであれば、それはそれらのレコードのすべてのがでメモリにロードされることを念頭に価値があります一度;返された結果を列挙するときに1つずつデータベースから取り出されることはありません。また、リソースがかなり消費される可能性があります(2回目の列挙を避けるために非常に多くのデータを扱っている場合) 。

これは、GetNonPagedQueryが返されるときにSQL接続が閉じられ、呼び出し元によって「オンデマンドで」データを読み取るためのオープン方法がないためです。大量のデータを実際に処理している場合は、ページングされていないクエリが最適なアプローチではないかもしれません。

上記のコードでは、「customAction」は、行を列挙するときにのみ呼び出され、GetNonPagedQueryが返される前にすべて実行されるわけではありません。 「customAction」が高価な操作である可能性がある場合は、このメリットがあります。 GetNonPagedQueryを返す前に、一方で、あなたは「のCustomActionは、」すべての結果のために呼び出すことがしたい場合、あなたはキャスト<ダイナミック>(後に1つの以上ToListメソッド()の呼び出しが必要になります)、それはあなたにとってより有用であるシナリオによって決まります。

0

はい、それは可能性がある:

Type Switching per Row程度Dapperのドキュメントのセクションを参照してください。私は、同じシステムを使用して、各行を読み込んで明示的に処理して結果を目的のフォーマットにマッサージすると、うまくいかないと思っています(つまり自分で試してみません)。

関連する問題