Azure Table Storage - Customising table entity saves for persisting collections
There's already a lot of blog posts out there about being able to hook into the WritingEntity event to customise the XML that gets submitted to the server, such as this.
Has anything changed with this process in the newer versions of the SDK? I ask because I have the following simple entity:
public class Label : TableServiceEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
public string ContactInfo { get; set; }
public List<string> Urls { get; set; }
public Label()
{
Urls = new List<string>():
}
}
I want to be able to persist that collection of URLs, and I'm already aware that the only thing that's supported directly in terms of arrays/collections is binary arrays. So I thought, fine, I'll just hook into that WritingEntity event and serialize that list to JSON/XML, then add that to the properties list as per that blog post. Then deserialize back to the list during the handling of the ReadEntity event.
However, when I do that, on the call to SaveChanges on the TableServiceContext I get a DataServiceRequest exception that contains an inner NotSupported exception with the message "Only collections of entities are supported". Is this because the String class doesn't inherit from TableEntity? The thing that's confusing me is, when I check the XML that it's written out, it has actually been able to successfully write the custom XML with the additionally added property containing the serialized list, despite the exception.
When I try to retrieve the label via CreateQuery, I get the same exception thrown.
Can anybody tell me what I'm doing wrong here, and what the best practice is for dealing with this situation? I've already came across Lokad Cloud for doing the persistence, but it doesn't seem ideal to me as the querying options for getting data back out are too limited for what I'm wanting to do.
I did have a look at past questions but none seem to address this issue directly.
Any advice would be appre开发者_StackOverflow社区ciated!
Based on the response: I don't know if you got the impression that I'm serializing the entire entity manually? The partition key is just "LABELX", where X is the first letter of the Name property of the label, and the row key is just the string representation of the GUID (I know it's wasteful to store both of those, but I'm just trying to get up and running at the moment).
If you set a breakpoint on the first line of the WritingEntity event and you inspect the XML that's in the e.Data property, there is nothing to represent the URLs collection in the XML. It doesn't matter whether the URLs list is empty, null, or it has entries in it - it doesn't appear at all in the XML, so it doesn't matter what list I pass in. So I think that should answer all 4 questions.
Inside the writing entity event, there really isn't anything special: just code to serialize the list to XML, and then code to add a property to the XML, as per the blog post - it all runs without any exceptions.
OK, sorry, I had neglected to mention that fact that I'm only using the development storage at the moment. The problem seemed to be the fact that I had created some Label entities that didn't have any URLs, before I had created ones that did, and so the schema information in the TableContainer table didn't have the additional URL property. After I cleaned out the database and added a fully populated object before adding anything else, everything worked OK!
I've got some code working on this - and it definitely seems to work with 1.4 SDK
My code is more based on generic entities and the sources I used for inspiration were:
- Jai's post on http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/481afa1b-03a9-42d9-ae79-9d5dc33b9297/
- with modifications from Yi-Lun Luo on http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/f57cb566-cc7a-4b31-b1ab-47b6d16604af/
- and also a good some credit due to ideas from http://azuretablequery.codeplex.com/
I'm guessing that something is wrong in your WritingEntity event handler. Can you post any more of your code - especially:
- how are you serialising the RowKey and PartitionKey?
- are you removing the raw Urls list from the serialisation?
- if you're using XML for the inner serialisation, then are you fully escaping that XML?
One further debugging idea is to just try to get the code working step by step - i.e.
- start with an entity with no list,
- then try adding another simple test property using a WritingEntity hook,
- then try adding a Urls list, and removing it during WritingEntity.
- then try serialising and adding this new property in WritingEntity
精彩评论