私は LINQ を理解していると思っていましたか、それとも理解していましたか? それとも、厄介な Oracle プロバイダーのバグでしょうか?
ノックアウト アプリにページングを実装したいという非常にイライラする状況になりました。Troy Goode の PagedList Mvc ライブラリを使用すると、コードが 2 つのアイテムを返す検索から 15 アイテムの結果に変換された場所を確認できます (ページングを 15 アイテムごとに設定していました)。SQL Server 2005/2008 では問題なく動作しましたが、Oracle.DataAccess.dll v11.2.3/v4.112.3 (バージョン番号の読み取り方法によって異なります) を使用するとうまくいきませんでした。
次のようにLinqで検索結果を実行しました。
var entities = _context.Entities;
var q = !string.IsNullOrEmpty(search)
? entities
.Where(a => a.PRODUCT_NUM.ToUpper().Contains(search.ToUpper())
|| a.PRINT_NAME.ToUpper().Contains(search.ToUpper()))
: entities;
var result = q.OrderBy(e => e.UPDATE_DATE == null)
.ThenByDescending(e => e.UPDATE_DATE)
.Select(r => new EntityModel
{
Id = r.ID,
Num = r.PRODUCT_NUM,
Name = r.PRINT_NAME,
City = r.City.PRINT_NAME,
State = r.City.State.PRINT_NAME,
EntityType = r.ENTITY_TYPE,
CompanyType = r.COMPANY_TYPE,
UpdateDate = r.UPDATE_DATE
})
.ToPagedList(pageNumber, 15);
この時点で、イミディエイト ウィンドウを使用して 2 つのアイテムを返すことができますが、ページング プロセスを経ると 15 のアイテムが返されます。
最初に考えたのは、キャッシングの問題か何かがあるのでしょうか? しかし、PagedList ライブラリを掘り下げました。https://github.com/TroyGoode/PagedList
PagedList に渡されたオブジェクトを見てみましょう。返されたレコードの数を示します。PagedList 内では、IQueryable オブジェクトはスーパーセットと呼ばれ、最終的には List を返しますが、Immediate Window を介してリストを照会すると何が得られるかを確認してください。それを見せるのが一番いいと思ったんだけど…
?superset.Take(pageSize).Count()
2
?superset.Count()
51114
?superset.Skip(0).Take(pageSize).Count()
2
?superset.ToList().Count()
2
?superset.Skip(0).Take(pageSize).ToList().Count()
15
?superset.Take(pageSize).ToList().Count()
15
私にとって最も興味深いのは、ToList() を実行すると、15 レコードが返されることです。Oracle ODP.NET プロバイダーの問題ですか? Ayende の Entity Framework Provider efprof.comを起動し、Oracle クエリが生成されているのを確認し、それを TOAD にコピー アンド ペーストしました。実際には 15 ではなく 2 項目が返されます。
私は間違いなく何かが欠けています。
ありがとう、ロブ