public TEntity AddOrUpdate(TKey key, Func <TEntity> addViewFactory, Func <TEntity, TEntity> updateViewFactory, AddOrUpdateHint hint) { string etag = null; var blob = GetBlobReference(key); TEntity view; try { // atomic entities should be small, so we can use the simple method var bytes = blob.DownloadByteArray(); using (var stream = new MemoryStream(bytes)) { view = _strategy.Deserialize <TEntity>(stream); } view = updateViewFactory(view); etag = blob.Attributes.Properties.ETag; } catch (StorageClientException ex) { switch (ex.ErrorCode) { case StorageErrorCode.ContainerNotFound: var s = string.Format( "Container '{0}' does not exist. You need to initialize this atomic storage and ensure that '{1}' is known to '{2}'.", blob.Container.Name, typeof(TEntity).Name, _strategy.GetType().Name); throw new InvalidOperationException(s, ex); case StorageErrorCode.BlobNotFound: case StorageErrorCode.ResourceNotFound: view = addViewFactory(); break; default: throw; } } // atomic entities should be small, so we can use the simple method // http://toolheaven.net/post/Azure-and-blob-write-performance.aspx using (var memory = new MemoryStream()) { _strategy.Serialize(view, memory); // note that upload from stream does weird things var bro = etag != null ? new BlobRequestOptions { AccessCondition = AccessCondition.IfMatch(etag) } : new BlobRequestOptions { AccessCondition = AccessCondition.IfNoneMatch("*") }; // make sure that upload is not rejected due to cashed content MD5 // http://social.msdn.microsoft.com/Forums/hu-HU/windowsazuredata/thread/4764e38f-b200-4efe-ada2-7de442dc4452 blob.Properties.ContentMD5 = null; blob.UploadByteArray(memory.ToArray(), bro); } return(view); }
public ProjectionInfo(IEnumerable <ViewInfo> views, object tempProjection, IDocumentStrategy strategy) { Condition.Requires(views, "views").IsNotNull(); Condition.Requires(tempProjection, "tempProjection").IsNotNull(); Condition.Requires(strategy, "strategy").IsNotNull(); this.ViewBuckets = views.Select(v => v.StoreBucket).ToArray(); var viewTypes = views.Select(v => v.EntityType); var projectionType = tempProjection.GetType(); this.Hash = new ProjectionHash(projectionType, viewTypes, strategy.GetType()); this.ProjectionName = projectionType.Name; this._checkpoint = new ProjectionCheckpoint(); this._tempProjection = tempProjection; }