Azure 表存储 - 自定义表实体保存以保存持久集合

发布于 2024-11-10 02:11:00 字数 1745 浏览 4 评论 0 原文

已经有很多博客文章介绍如何连接到writingEntity事件来自定义提交到服务器的XML,例如这个

在新版本的 SDK 中,此过程有什么变化吗?我问这个问题是因为我有以下简单实体:

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>():
    }
}

我希望能够保留该 URL 集合,并且我已经知道数组/集合直接支持的唯一东西是二进制数组。所以我想,好吧,我只需挂入那个 WriteEntity 事件并将该列表序列化为 JSON/XML,然后根据该博客文章将其添加到属性列表中。然后在处理 ReadEntity 事件期间反序列化回列表。

但是,当我这样做时,在调用 TableServiceContext 上的 SaveChanges 时,我收到一个 DataServiceRequest 异常,其中包含内部 NotSupported 异常,并显示消息“仅支持实体集合”。这是因为 String 类不是从 TableEntity 继承的吗?让我感到困惑的是,当我检查它写出的 XML 时,它实际上已经能够使用包含序列化列表的附加添加属性成功编写自定义 XML,尽管有例外。

当我尝试通过 CreateQuery 检索标签时,我抛出了相同的异常。

谁能告诉我我在这里做错了什么,以及处理这种情况的最佳做法是什么?我已经遇到过 Lokad Cloud 来进行持久化,但它并没有对我来说似乎很理想,因为获取数据的查询选项对于我想做的事情来说太有限了。

我确实查看了过去的问题,但似乎没有一个直接解决这个问题。

任何建议将不胜感激!

根据回复: 不知道大家是否有这样的印象:我是手动序列化整个实体的?分区键只是“LABELX”,其中 X 是标签的 Name 属性的第一个字母,行键只是 GUID 的字符串表示形式(我知道存储这两者很浪费,但我目前只是想启动并运行)。

如果您在 WriteEntity 事件的第一行设置断点并检查 e.Data 属性中的 XML,则 XML 中没有任何内容可以表示 URL 集合。 URL 列表是否为空、为 null,或者其中包含条目并不重要 - 它根本不会出现在 XML 中,因此我传入哪个列表并不重要。所以我认为应该回答所有 4 个问题。

在写入实体事件中,实际上没有什么特别的:只是将列表序列化为 XML 的代码,然后将属性添加到 XML 的代码,如博客文章所述 - 一切都运行,没有任何异常。


好吧,抱歉,我忘记提及我目前只使用开发存储这一事实。问题似乎是这样的事实:在创建具有任何 URL 的标签实体之前,我创建了一些没有任何 URL 的标签实体,因此 TableContainer 表中的架构信息没有附加的 URL 属性。在我清理数据库并在添加其他任何内容之前添加一个完全填充的对象之后,一切正常!

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 appreciated!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怪我入戏太深 2024-11-17 02:11:00

我有一些代码正在处理这个问题 - 它似乎确实适用于 1.4 SDK

我的代码更多地基于通用实体,我用于灵感的来源是:

猜测您的 WriteEntity 事件处理程序中出现了问题。您能否发布更多代码 - 特别是:

  • 您如何序列化 RowKey 和 PartitionKey?
  • 您是否从序列化中删除原始 URL 列表?
  • 如果您使用 XML 进行内部序列化,那么您是否完全转义该 XML?

进一步的调试想法是尝试让代码逐步运行 - 即

  1. 从没有列表的实体开始,
  2. 然后尝试使用writingEntity钩子添加另一个简单的测试属性,
  3. 然后尝试添加Urls列表,并在WritingEntity期间将其删除。
  4. 然后尝试序列化并在writingEntity中添加这个新属性

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:

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.

  1. start with an entity with no list,
  2. then try adding another simple test property using a WritingEntity hook,
  3. then try adding a Urls list, and removing it during WritingEntity.
  4. then try serialising and adding this new property in WritingEntity
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文