通过OData访问的Azure表存储实体。 PartitionKey和RowKey作为主键

时间:2012-09-10 16:11:52

标签: .net wcf-data-services visual-studio-2012 odata azure-table-storage

我正在通过OData(WCF数据服务)使用Azure表存储访问“Person”实体。我有很多问题要让它发挥作用。我遇到了这个错误:

实体代码:

public class Person : TableServiceEntity
{
public string Name { get; set; }
... etc

URI:      http://127.0.0.1/DataService/PersonDataService.svc/Person

结果:

  

服务器在处理请求时遇到错误。例外   消息是'在数据上下文类型'PersonDataServiceContext',有   顶级IQueryable属性'Person',其元素类型不是实体   类型。确保IQueryable属性是实体类型或   将数据上下文类型指定为IgnoreProperties属性   忽略这个属性。'。

经过大量的故障排除后,我发现通过此post,为了解决此错误,我可以添加到我的实体中:

1)[DataServiceKey]属性添加自定义键(我需要[DataServiceKey(“PartitionKey”,“RowKey”)])

2)通过寻找“PersonID”属性(这是唯一适合我的属性)

3)通过寻找“ID”属性

没有1是唯一适合我的人。我不得不添加一个“PersonID”列,如下所示:

实体代码:

public class Person : TableServiceEntity
{
public Guid PersonID { get; set; } //This is absolutely necessary to get around the aforementioned error
public string Name { get; set; }
... etc

我通过 http://127.0.0.1/DataService/PersonDataService.svc/Person 或通过指定PersonID成功获取数据: http://127.0.0.1/DataService/PersonDataService.svc/Person(guid'e4a924d1-a564-45d7-9e3e-fe0396d08f8e')

我想指定一个自定义主键列,例如PartitionKey / RowKey(来自TableServiceEntity),但使用此代码没有帮助:

[DataServiceKey("PartitionKey", "RowKey")]
public class Person : TableServiceEntity
{
public string Name { get; set; }
... etc

这是一个错误吗? 对于我拥有的每个实体,我是否必须遵循该惯例? Person => PersonID,Foo => FooID等

我正在使用Visual Studio 2012和Silverlight 5,.NET Framework 4.0。

2 个答案:

答案 0 :(得分:0)

这是一个非常接近你正在尝试的样本

Windows Azure Walkthrough: Table Storage

Understanding the Table Service Data Model

每个条目都有一个PartitionKey和一个RowKey,并且组合必须是唯一的。根据第一个链接,rowkey可以是string.empty。

答案 1 :(得分:0)

根据WCF Data Service and Azure Table Storage: How can I use PartitionKey / RowKey as primary keys ...

这似乎是反射提供者的限制,可能不是预期的限制。我会在内部将此文件作为错误提交,但这是一个解决方法,直到我们进行修复...

您可以使用new modifier隐藏通过基类传递所需的值:

using System;
using System.Data.Services.Common;

namespace SO.OData
{
    [DataServiceKey("PartitionKey", "RowKey")]
    public class Question : TableServiceEntry
    {
        public new string PartitionKey
        {
            get { return base.PartitionKey; }
            set { base.PartitionKey = value; }
        }

        public new string RowKey
        {
            get { return base.RowKey; }
            set { base.RowKey = value; }
        }

        public string Text { get; set; }
        public User AskedBy { get; set; }
        public DateTimeOffset AskedAt { get; set; }
    }

    public abstract class TableServiceEntry
    {
        public string PartitionKey { get; set; }
        public string RowKey { get; set; }
    }
}