Пример #1
0
        /// <summary>
        /// Inserts an entity only if a with the same PartitionKey and RowKey does not already exist.
        /// </summary>
        /// <param name="item"></param>
        public TableEntityProxy <T> Insert(T item)
        {
            var table = GetTable();

            table.CreateIfNotExists();

            var wrap = new TableEntityProxy <T>(item)
            {
                PartitionKey = PartitionKey(item),
                RowKey       = RowKey(item)
            };

            if (String.IsNullOrEmpty(wrap.PartitionKey))
            {
                throw new ArgumentNullException("PartitionKey", "The partition key function resulted in a null partition key.");
            }
            if (String.IsNullOrEmpty(wrap.RowKey))
            {
                throw new ArgumentNullException("RowKey", "The row key function resulted in a null row key.");
            }
            var insertOperation = TableOperation.Insert(wrap);

            table.Execute(insertOperation);
            return(wrap);
        }
        /// <summary>
        /// Gets all sequence definitions available.
        /// </summary>
        /// <returns></returns>
        public IEnumerable <SequenceIdStore> GetSequenceIdStores()
        {
            var schemas   = SchemaTableProxy.QueryPartitions("0", "zzzzz");
            var sequences = SequenceTableProxy.QueryPartitions("0", "zzzzz") ?? new List <TableEntityProxy <DynamicTableEntity> >();
            var stores    = new List <SequenceIdStore>();

            foreach (var schema in schemas)
            {
                var sequence =
                    sequences.FirstOrDefault(x =>
                                             String.Equals(schema.Entity.TableName, x.Entity[TableConstants.PartitionKey].StringValue,
                                                           StringComparison.InvariantCultureIgnoreCase));
                if (sequence == null)
                {
                    sequence = new TableEntityProxy <DynamicTableEntity>(new DynamicTableEntity(schema.PartitionKey, schema.RowKey, "",
                                                                                                new Dictionary <string, EntityProperty>()));
                    sequence.Entity.Properties.Add(PropertyFinalCachedId, new EntityProperty(schema.Entity.SeedValue));
                    SequenceTableProxy.Insert(sequence.Entity); //this could throw if another thread created after SequenceTableProxy.QueryPartitions was called above.
                }
                stores.Add(new SequenceIdStore
                {
                    FinalCachedId = sequence.Entity.Properties[PropertyFinalCachedId].StringValue,
                    Schema        = schema.Entity
                });
            }
            return(stores);
        }
Пример #3
0
        /// <summary>
        /// Updates an item on the server if it has not been updated since you last retrieved it.
        /// </summary>
        /// <param name="item"></param>
        /// <param name="eTag">The concurrency eTag supplied when you retrieved the item.</param>
        public TableEntityProxy <T> Update(T item, Func <T, String> eTag)
        {
            var table = GetTable();

            if (!table.Exists())
            {
                throw new InvalidOperationException(String.Format("Table '{0}' does not exist.  Update not possible.", table.Name));
            }

            var pKey = PartitionKey(item);
            var rKey = RowKey(item);

            var retrieveOperation = TableOperation.Retrieve <TableEntityProxy <T> >(pKey, rKey);
            var retrievedResult   = table.Execute(retrieveOperation);

            if (retrievedResult.Result == null)
            {
                throw new InvalidOperationException("The item specified for update does not exist.  Try an insert instead.");
            }

            var updateEntity = (TableEntityProxy <T>)retrievedResult.Result;

            if (updateEntity.ETag != eTag(item))
            {
                throw new InvalidOperationException("The item was changed since you retrieved it.");
            }

            var wrap = new TableEntityProxy <T>(item)
            {       //Putting ETag on this entity update allows it to replace the item in the table storage.
                PartitionKey = pKey,
                RowKey       = rKey,
                ETag         = updateEntity.ETag,
                Timestamp    = updateEntity.Timestamp
            };

            if (String.IsNullOrEmpty(wrap.PartitionKey))
            {
                throw new ArgumentNullException("PartitionKey", "The partition key function resulted in a null partition key.");
            }
            if (String.IsNullOrEmpty(wrap.RowKey))
            {
                throw new ArgumentNullException("RowKey", "The row key function resulted in a null row key.");
            }
            if (String.IsNullOrEmpty(updateEntity.ETag))
            {
                throw new ArgumentNullException("ETag", "An Etag is required on an entity to perform an update.");
            }
            var updateOperation = TableOperation.Replace(wrap);

            table.Execute(updateOperation);
            return(wrap);
        }
Пример #4
0
        /// <summary>
        /// Updates a wrapped item that was retrieved and edited.
        /// </summary>
        /// <param name="item"></param>
        public void Update(TableEntityProxy <T> item)
        {
            var table = GetTable();

            if (!table.Exists())
            {
                throw new InvalidOperationException(String.Format("Table '{0}' does not exist.  Update not possible.", table.Name));
            }

            var update = TableOperation.Replace(item);

            table.Execute(update);
        }
Пример #5
0
        /// <summary>
        /// Deletes an item only if it has not changed since the item was retrieved.
        /// </summary>
        /// <param name="item">An item that must have the ETag supplied from a prior retrieval.</param>
        public void Delete(TableEntityProxy <T> item)
        {
            var table = GetTable();

            if (!table.Exists())
            {
                throw new InvalidOperationException(String.Format("Table '{0}' does not exist.  Delete not possible.", table.Name));
            }

            var deleteOperation = TableOperation.Delete(item);
            var result          = table.Execute(deleteOperation);

            if (result.HttpStatusCode != 204) //204 = "No Content" = Successful delete per Azure docs
            {
                throw new InvalidOperationException(String.Format("Failed to delete {0}.  Status Code {1}. {2}", table.Name, result.HttpStatusCode, result.Result));
            }
        }
        private TableEntityProxy <DynamicTableEntity> CreateSequenceFromSchema(string tableName)
        {
            var schema = SchemaTableProxy.Get(tableName.GetValidPartitionKey(), tableName.GetValidRowKey());

            if (schema == null)
            {
                throw new ArgumentException(String.Format("Sequence '{0}' is not defined.  Cannot get the latest reserved key value.", tableName));
            }

            var sequence = new TableEntityProxy <DynamicTableEntity>(new DynamicTableEntity(schema.PartitionKey, schema.RowKey, "",
                                                                                            new Dictionary <string, EntityProperty>()));

            sequence.Entity.Properties.Add(PropertyFinalCachedId, new EntityProperty(schema.Entity.SeedValue));
            SequenceTableProxy.Insert(sequence.Entity);
            //Insert would throw if another thread created after SequenceTableProxy.Get was called above.  Only one thread can create the sequence.
            //  - a lock would not help, since the other thread may be in another role (web or worker) instance
            return(sequence);
        }
Пример #7
0
        /// <summary>
        /// Inserts or Updates an entity whether it is on the server or not.  Use this when you don't care about concurrency.
        /// </summary>
        /// <param name="item"></param>
        public TableEntityProxy <T> InsertOrUpdate(T item)
        {
            var table = GetTable();

            table.CreateIfNotExists();

            var pKey = PartitionKey(item);
            var rKey = RowKey(item);

            var wrap = new TableEntityProxy <T>(item)
            {
                PartitionKey = pKey,
                RowKey       = rKey
            };

            if (String.IsNullOrEmpty(wrap.PartitionKey))
            {
                throw new ArgumentNullException("PartitionKey", "The partition key function resulted in a null partition key.");
            }
            if (String.IsNullOrEmpty(wrap.RowKey))
            {
                throw new ArgumentNullException("RowKey", "The row key function resulted in a null row key.");
            }

            var retrieveOperation = TableOperation.Retrieve <TableEntityProxy <T> >(pKey, rKey);
            var retrievedResult   = table.Execute(retrieveOperation);

            if (retrievedResult.Result == null)
            {
                var insertOrReplace = TableOperation.InsertOrReplace(wrap);
                table.Execute(insertOrReplace);
                return(wrap);
            }

            var updateEntity = (TableEntityProxy <T>)retrievedResult.Result;

            wrap.ETag      = updateEntity.ETag;
            wrap.Timestamp = updateEntity.Timestamp;

            var updateOperation = TableOperation.InsertOrReplace(wrap);

            table.Execute(updateOperation);
            return(wrap);
        }
Пример #8
0
        /// <summary>
        /// Insert up to 100 items as a  batch. (Azure limit per batch).
        /// Batches of any larger size are broken into smaller batches.
        /// </summary>
        /// <param name="items"></param>
        public List <TableEntityProxy <T> > InsertBatch(IEnumerable <T> items)
        {
            var table = GetTable();

            table.CreateIfNotExists();

            var batchOperation = new TableBatchOperation();
            var wrappedItems   = new List <TableEntityProxy <T> >();

            Int32 batchSize = 0;

            foreach (var item in items)
            {
                if (batchSize == 100)
                {   //hit max batch size, break it into pieces.
                    table.ExecuteBatch(batchOperation);
                    batchSize      = 0;
                    batchOperation = new TableBatchOperation();
                }
                var wrap = new TableEntityProxy <T>(item)
                {
                    PartitionKey = PartitionKey(item),
                    RowKey       = RowKey(item)
                };
                if (String.IsNullOrEmpty(wrap.PartitionKey))
                {
                    throw new ArgumentNullException("PartitionKey", "The partition key function resulted in a null partition key.");
                }
                if (String.IsNullOrEmpty(wrap.RowKey))
                {
                    throw new ArgumentNullException("RowKey", "The row key function resulted in a null row key.");
                }
                wrappedItems.Add(wrap);
                batchOperation.Insert(wrap);
                batchSize++;
            }

            if (batchSize > 0)
            {
                table.ExecuteBatch(batchOperation);
            }
            return(wrappedItems);
        }