public void RemoveTags(string photoId, Tag[] tags)
        {
            var context = new PhotoAlbumDataContext();

            foreach (var tag in tags)
            {
                var photoTag = new PhotoTagRow(photoId, tag.Name);
                context.AttachTo(PhotoAlbumDataContext.PhotoTagTable, photoTag, "*");
                context.DeleteObject(photoTag);
            }

            try
            {
                // continue trying to delete, even if not found
                context.SaveChanges(SaveChangesOptions.ContinueOnError);
            }
            catch (DataServiceRequestException ex)
            {
                foreach (var resp in ex.Response)
                {
                    // to be more robust, we will ignore 404 errors when
                    // the entity might have already been deleted (due to an
                    // incomplete operation earliet).
                    if (resp.StatusCode != (int)HttpStatusCode.NotFound &&
                        resp.StatusCode != (int)HttpStatusCode.OK)
                    {
                        throw;
                    }
                }
            }
        }
        public void Delete(Photo photo)
        {
            var context  = new PhotoAlbumDataContext();
            var photoRow = new PhotoRow(photo);

            context.AttachTo(PhotoAlbumDataContext.PhotoTable, photoRow, "*");
            context.DeleteObject(photoRow);
            context.SaveChanges();

            // tell the worker role to clean up blobs and tags
            this.SendToQueue(
                Constants.PhotoCleanupQueue,
                string.Format(CultureInfo.InvariantCulture, "{0}|{1}|{2}|{3}|{4}|{5}", photo.PhotoId, photo.Owner, photo.Url, photo.RawTags, photo.ThumbnailUrl, photo.AlbumId));
        }
        public void DeleteAlbum(string albumName, string owner)
        {
            var context = new PhotoAlbumDataContext();

            // find the album by name and owner (we don't pass in ugly GUIDs for direct access
            var album = context.Albums
                        .Where(a => a.AlbumId == albumName && a.PartitionKey == owner.ToLowerInvariant()).AsTableServiceQuery()
                        .Single();

            context.DeleteObject(album);
            context.SaveChanges();

            // tell the worker role to clean up blobs and tags
            this.SendToQueue(
                Constants.AlbumCleanupQueue,
                string.Format(CultureInfo.InvariantCulture, "{0}|{1}", owner, album.AlbumId));
        }
        public void DeleteAlbum(string albumName, string owner)
        {
            var context = new PhotoAlbumDataContext();

            // find the album by name and owner (we don't pass in ugly GUIDs for direct access
            var album = context.Albums
                .Where(a => a.AlbumId == albumName && a.PartitionKey == owner.ToLowerInvariant()).AsTableServiceQuery()
                .Single();

            context.DeleteObject(album);
            context.SaveChanges();

            // tell the worker role to clean up blobs and tags
            this.SendToQueue(
                Constants.AlbumCleanupQueue,
                string.Format(CultureInfo.InvariantCulture, "{0}|{1}", owner, album.AlbumId));
        }
        public void RemoveTags(string photoId, Tag[] tags)
        {
            var context = new PhotoAlbumDataContext();

            foreach (var tag in tags)
            {
                var photoTag = new PhotoTagRow(photoId, tag.Name);
                context.AttachTo(PhotoAlbumDataContext.PhotoTagTable, photoTag, "*");
                context.DeleteObject(photoTag);
            }

            try
            {
                // continue trying to delete, even if not found
                context.SaveChanges(SaveChangesOptions.ContinueOnError);
            }
            catch (DataServiceRequestException ex)
            {
                foreach (var resp in ex.Response)
                {
                    // to be more robust, we will ignore 404 errors when
                    // the entity might have already been deleted (due to an
                    // incomplete operation earliet).
                    if (resp.StatusCode != (int)HttpStatusCode.NotFound
                        && resp.StatusCode != (int)HttpStatusCode.OK)
                    {
                        throw;
                    }
                }
            }
        }
        public void Delete(Photo photo)
        {
            var context = new PhotoAlbumDataContext();
            var photoRow = new PhotoRow(photo);

            context.AttachTo(PhotoAlbumDataContext.PhotoTable, photoRow, "*");
            context.DeleteObject(photoRow);
            context.SaveChanges();

            // tell the worker role to clean up blobs and tags
            this.SendToQueue(
                Constants.PhotoCleanupQueue,
                string.Format(CultureInfo.InvariantCulture, "{0}|{1}|{2}|{3}|{4}|{5}", photo.PhotoId, photo.Owner, photo.Url, photo.RawTags, photo.ThumbnailUrl, photo.AlbumId));
        }