RavenDb學習(九)高階特性下半部分
阿新 • • 發佈:2022-04-29
1.聚合快取 RavenDb預設是快取所有的請求url的,最大的快取請求數預設是2048 documentStore.Conventions.ShouldCacheRequest = url => true; documentStore.MaxNumberOfCachedRequests = 2048; 如果開啟這個選項,RavenDb直接從快取當中讀取資料,而不是從服務端。 //關閉跟蹤 documentStore.Conventions.ShouldAggressiveCacheTrackChanges = false; using (session.Advanced.DocumentStore.AggressivelyCacheFor(TimeSpan.FromMinutes(5))) { var user = session.Load<User>("users/1"); } using (session.Advanced.DocumentStore.AggressivelyCacheFor(TimeSpan.FromMinutes(5))) { var user = session.Load<User>("users/1"); } //啟動強制檢查更新,在SaveChanges之後 documentStore.Conventions.ShouldSaveChangesForceAggresiveCacheCheck = true; 2、客戶端Listener Document Conflict listeners (IDocumentConflictListener), Document Conversion listeners (IDocumentConversionListener) Document Delete listeners (IDocumentDeleteListener) Document Query listeners (IDocumentQueryListener) Document Store listeners (IDocumentStoreListener) 例子1: public class TakeNewestConflictResolutionListener : IDocumentConflictListener { public bool TryResolveConflict(string key, JsonDocument[] conflictedDocs, out JsonDocument resolvedDocument) { var maxDate = conflictedDocs.Max(x => x.LastModified); resolvedDocument = conflictedDocs.FirstOrDefault(x => x.LastModified == maxDate); return resolvedDocument != null; } } 例子2: public class Custom { public string Id { get; set; } public string Name { get; set; } public string Value { get; set; } } public class MetadataToPropertyConversionListener : IDocumentConversionListener { public void EntityToDocument(string key, object entity, RavenJObject document, RavenJObject metadata) { if (entity is Custom == false) return; document.Remove("Value"); } public void DocumentToEntity(string key, object entity, RavenJObject document, RavenJObject metadata) { if (entity is Custom == false) return; ((Custom)entity).Value = metadata.Value<string>("Raven-Document-Revision"); } } 例子3: public class FailDelete : IDocumentDeleteListener { public void BeforeDelete(string key, object entityInstance, RavenJObject metadata) { throw new NotSupportedException(); } } 例子4: public class NonStaleQueryListener : IDocumentQueryListener { public void BeforeQueryExecuted(IDocumentQueryCustomization customization) { customization.WaitForNonStaleResults(); } } 例子5: public class FilterForbiddenKeysDocumentListener : IDocumentStoreListener { private readonly IList<string> forbiddenKeys = new List<string> { "system" }; public bool BeforeStore(string key, object entityInstance, RavenJObject metadata, RavenJObject original) { return this.forbiddenKeys.Any(x => x.Equals(key, StringComparison.InvariantCultureIgnoreCase)) == false; } public void AfterStore(string key, object entityInstance, RavenJObject metadata) { } } 3、批量插入 //批量插入程式碼示例 using (var bulkInsert = store.BulkInsert()) { for (int i = 0; i < 1000 * 1000; i++) { bulkInsert.Store(new User { Name = "Users #" + i }); } } //批量插入介面原型 public interface IDocumentStore { BulkInsertOperation BulkInsert(string database = null, BulkInsertOptions options = null); } //批量插入選項原型 public class BulkInsertOptions { public bool CheckForUpdates { get; set; } public bool CheckReferencesInIndexes { get; set; } public int BatchSize { get; set; } } //批量插入操作原型 public class BulkInsertOperation { public delegate void BeforeEntityInsert(string id, RavenJObject data, RavenJObject metadata); public event BeforeEntityInsert OnBeforeEntityInsert = delegate { }; public event Action<string> Report { ... } public void Store(object entity) { ... } public void Store(object entity, string id) { ... } } 4、流式查詢 預設的分頁查詢的,但是有時候,我們需要一次性查詢,RavenDb提供了一種流式查詢的方式 //正常查詢 var query = session.Query<User>("Users/ByActive").Where(x => x.Active); using (var enumerator = session.Advanced.Stream(query)) { while (enumerator.MoveNext()) { User activeUser = enumerator.Current.Document; } } //lucene查詢 var luceneQuery = session.Advanced.LuceneQuery<User>("Users/ByActive").Where("Active:true"); using (var enumerator = session.Advanced.Stream(luceneQuery)) { while (enumerator.MoveNext()) { User activeUser = enumerator.Current.Document; } } //介面原型 QueryHeaderInformation queryHeaderInformation; session.Advanced.Stream(query, out queryHeaderInformation); public class QueryHeaderInformation { public string Index { get; set; } public bool IsStable { get; set; } public DateTime IndexTimestamp { get; set; } public int TotalResults { get; set; } public Etag ResultEtag { get; set; } public Etag IndexEtag { get; set; } } //分頁 using (var enumerator = session.Advanced.Stream<User>(fromEtag: Etag.Empty, start: 0, pageSize: int.MaxValue)) { while (enumerator.MoveNext()) { User activeUser = enumerator.Current.Document; } } // using (var enumerator = session.Advanced.Stream<User>(startsWith: "users/", matches: "*Ra?en", start: 0, pageSize: int.MaxValue)) { while (enumerator.MoveNext()) { User activeUser = enumerator.Current.Document; } } //非同步版本 using (var asyncSession = store.OpenAsyncSession()) { var query = asyncSession.Query<User>("Users/ByActive").Where(x => x.Active); using (var enumerator = await asyncSession.Advanced.StreamAsync(query)) { while (await enumerator.MoveNextAsync()) { User activeUser = enumerator.Current.Document; } } using (var enumerator = await asyncSession.Advanced.StreamAsync<User>(Etag.Empty)) { while (await enumerator.MoveNextAsync()) { User activeUser = enumerator.Current.Document; } } }