さて、私たちはMVC C#& MongoDBを使用してシステムを開発しています。最初に開発したときには、リポジトリのパターンに従うことをお勧めします(これはお尻の痛みです)。現在実装されていることを示すコードがあります。リポジトリパターン使用時のMongoDBと大きなデータセット
MongoRepositoryクラス:
public class MongoRepository { }
public class MongoRepository<T> : MongoRepository, IRepository<T>
where T : IEntity
{
private MongoClient _client;
private IMongoDatabase _database;
private IMongoCollection<T> _collection;
public string StoreName {
get {
return typeof(T).Name;
}
}
}
public MongoRepository() {
_client = new MongoClient(ConfigurationManager.AppSettings["MongoDatabaseURL"]);
_database = _client.GetDatabase(ConfigurationManager.AppSettings["MongoDatabaseName"]);
/* misc code here */
Init();
}
public void Init() {
_collection = _database.GetCollection<T>(StoreName);
}
public IQueryable<T> SearchFor() {
return _collection.AsQueryable<T>();
}
}
IRepositoryインタフェースクラス:
public interface IRepository { }
public interface IRepository<T> : IRepository
where T : IEntity
{
string StoreNamePrepend { get; set; }
string StoreNameAppend { get; set; }
IQueryable<T> SearchFor();
/* misc code */
}
は、リポジトリは、その後Ninjectを使用してインスタンス化されますが、それは次のようになりますことなしに(ただ、これは簡単にするために例:
MongoRepository<Client> clientCol = new MongoRepository<Client>();
ここでは、 chページは、DataTableが読み込まれるテーブルのJSONを出力するコントローラアクションにフィードするために使用されます。コレクションは(正確には99905)レコードをたくさん持っている場合は、データ場合
はtmpFinalList = clientCol
.SearchFor()
.OrderBy(tmpOrder) // tmpOrder = "ClientDescription DESC"
.Skip(Start) // Start = 99900
.Take(PageLength) // PageLength = 10
.ToList();
さて問題は、すべてが正常に動作していること:LINQは、文字列の入力から構築することができるように、次はDynamicLinqを使用していることに注意してください私たちのキーフィールドは5文字の固定長の文字列であり、このクエリを使用してSkip and Take Fineを行うことができます。しかし、ClientDescriptionのようなものであれば、「並べ替え」や「並べ替える」ことができます(つまりページ1)。しかし、Skip = 99900で最後にページを移動したとき& Take = 10次のメモリエラー:
An exception of type 'MongoDB.Driver.MongoCommandException' occurred in MongoDB.Driver.dll but was not handled in user code
Additional information: Command aggregate failed: exception: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting. Aborting operation. Pass allowDiskUse:true to opt in..
これは分かりやすいと思います。私はインターネットを見ていて、ほとんどが提案されているすべてがアグリゲーションと "allowDiskUse:true"を使用することですが、IRepositoryでIQueryableを使用しているので、IAggregateFluent <を使用することはできません> MongoDB関連クラスをIRepositoryに公開する必要があるIoCプリンシパルに反対する
IQueryableにこれを強制的に使用させる方法はありますか、誰かがIoCプリンシパルを使わずにIAggregateFluentにアクセスする手段を知っていますか?
ソートが1ページ目(Start = 0、Take = 10)で動作するのはなぜですか?私が最後まで検索すると失敗します...確かに、 (Start = 99900、Take = 10)は、同じ量のソートが必要なだけで、MongoDBは私に最後の5つ程度のレコードを送ってください。どちらのソートを行ってもこのエラーは発生しません。
ANSWER
オーケーMongoDBはC#のドライバの最新バージョンへのクレイグ・ウィルソンアップグレード@の助けを借りてとMongoRepositoryに次のように変更しても問題が解決されますので:
public IQueryable<T> SearchFor() {
return _collection.AsQueryable<T>(new AggregateOptions { AllowDiskUse = true });
}
私はSystem.MissingMethodExceptionを取得していましたが、これは更新が必要な他のMongoDBドライバのコピーによっても発生しました。
ああ、私がいたバージョンv2.2.0.262と利用可能な唯一の署名を使用しています:)新しいthatsの!私はアップグレードしようとします。 – Dwiea
Hmmm今、次のエラーが表示されています。削除して再度参照を追加しようとしました.eLinksWebPortal.dllで 'System.MissingMethodException'タイプの例外が発生しましたが、ユーザーコードで処理されませんでした。 追加情報: 'MongoDB .Driver.Linq.IMongoQueryable'1 MongoDB.Driver.IMongoCollectionExtensions.AsQueryable(MongoDB.Driver.IMongoCollection'1 、MongoDB.Driver.AggregateOptions) '._ – Dwiea
ヘルプCraigに感謝します:) – Dwiea