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; } } }