Azure 表存储、WCF 服务和枚举

发布于 2024-10-15 12:05:43 字数 1300 浏览 3 评论 0原文

这是我的问题。定义订单的类有一个名为 PaymentStatus 的属性,它是一个定义如下的 enum

    public enum PaymentStatuses : int
    {
        OnDelivery = 1,
        Paid = 2,
        Processed = 3,
        Cleared = 4
    }

然后,在类本身中,属性定义非常简单:

    public PaymentStatuses? PaymentStatus { get; set; }

但是,如果我尝试将订单保存到 Azure 表存储,则会出现以下异常:

System.InvalidOperationException: The type Order+PaymentStatuses' has no settable properties.

此时我认为使用 enum 是不可能的,但快速 Google 搜索返回了以下内容:http://social.msdn.microsoft .com/Forums/en-US/windowsazure/thread/7eb1a2ca-6c1b-4440-b40e-012db98ccb0a

此页面列出了两个答案,其中一个似乎忽略了问题,并建议使用 enum< Azure 存储中的 /code> 没问题。

现在,我不需要将enum存储在Azure表存储中,我也可以存储相应的int,但是,我确实需要这个属性在 WCF 服务中公开。

我尝试让属性使用 getset 从存储的 integer 返回 enum,并删除通过在我的 DataContext 上使用 WritingEntity 事件从 Azure 获取此属性,但我在触发该实体的事件之前收到该异常。

此时,我不知所措,我不知道我还能做些什么来将此属性作为 enum 放在 WCF 中,但让 Azure 仅存储 int代码>.

Here's my problem. A class which defines an order has a property called PaymentStatus, which is an enum defined like so:

    public enum PaymentStatuses : int
    {
        OnDelivery = 1,
        Paid = 2,
        Processed = 3,
        Cleared = 4
    }

And later on, in the class itself, the property definition is very simple:

    public PaymentStatuses? PaymentStatus { get; set; }

However, if I try to save an order to the Azure Table Storage, I get the following exception:

System.InvalidOperationException: The type Order+PaymentStatuses' has no settable properties.

At this point I thought using enum isn't possible, but a quick Google search returned this: http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/7eb1a2ca-6c1b-4440-b40e-012db98ccb0a

This page lists two answers, one of which seems to ignore the problems and suggests that using an enum in Azure Storage is fine.

Now, I don't NEED to store the enum in the Azure Table Storage as such, I could just as well store a corresponding int, however, I do need this property to be exposed in the WCF service.

I've tried making the property use get and set to return the enum from a stored integer, and remove this property from Azure by using the WritingEntity event on my DataContext, but I get that exception before the event for this entity is fired.

At this point, I'm at a loss, I don't know what else I can do to have this property in WCF as an enum, but have Azure store just the int.

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

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

发布评论

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

评论(6

一指流沙 2024-10-22 12:05:43

不支持枚举。尽管它的定义类似于 int,但它实际上不是表存储支持的整型类型。 这是类型列表支持。 枚举只是具有面向对象风格的整数的字符串表达式。

您可以将 int 存储在表存储中,然后使用 Enum.Parse 进行转换。

Enum is not supported. Even though it is defined like an int, it is really not an integral type supported by Table Storage. Here is the list of types supported. An enum is just a string expression of an integral number with an object-oriented flavor.

You can store int in table storage and then convert it using Enum.Parse.

无声情话 2024-10-22 12:05:43

这里有一个简单的解决方法:

public int MyEnumValue { get; set; } //for use by the Azure client libraries only
[IgnoreProperty] public MyEnum MyEnum
{
    get { return (MyEnum) MyEnumValue; }
    set { MyEnumValue = (int) value; }
}

如果可以使用一个简单的支持值而不是额外的(公共!)属性,那就更好了 - 没有覆盖 ReadEntity/WriteEntity 当然。我打开了一个用户语音票来促进这一点,所以你可能想投票。

Here's a simple workaround:

public int MyEnumValue { get; set; } //for use by the Azure client libraries only
[IgnoreProperty] public MyEnum MyEnum
{
    get { return (MyEnum) MyEnumValue; }
    set { MyEnumValue = (int) value; }
}

It would have been nicer if a simple backing value could have been employed rather than an additional (public!) property - without the hassle of overriding ReadEntity/WriteEntity of course. I opened a user voice ticket that would facilitate that, so you might want to upvote it.

土豪 2024-10-22 12:05:43

是的,我也遇到了同样的问题
我将之前的 enum 属性更改为 int 属性。现在这个 int 属性解析传入的 int 并将其保存到相同枚举类型的变量中,所以现在代码被

public CompilerOutputTypes Type 
{get; set;}

更改为

private CompilerOutputTypes type;
public int Type 
{
  get {return (int)type;}
  set { type = (CompilerOutputTypes)value; }
}

ya i was having this same problem
i changed my property which was earlier enum to int. now this int property parses the incoming int and saves it into a variale of the same enum type so now the code that was

public CompilerOutputTypes Type 
{get; set;}

is chaged to

private CompilerOutputTypes type;
public int Type 
{
  get {return (int)type;}
  set { type = (CompilerOutputTypes)value; }
}
荒路情人 2024-10-22 12:05:43

只是建议...

我记得在 WCF 中您必须使用特殊属性标记枚举: http://msdn.microsoft.com/en-us/library/aa347875.aspx

另外,当您声明 PaymentStatuses 时? PaymentStatus,您声明 Nullable付款状态? 语法只是语法糖。尝试删除 ? 并看看会发生什么(您可以添加 PaymentStatuses.NoSet = 0 ,因为 Int32 的默认值为 0)。

祝你好运。

Just suggestions...

I remember that in WCF you have to mark enums with special attributes: http://msdn.microsoft.com/en-us/library/aa347875.aspx

Also, when you declare PaymentStatuses? PaymentStatus, you are declaring Nullable<PaymentStatuses> PaymentStatus. The ? sintax is just syntactic sugar. Try to remove the ? and see what happen (you could add a PaymentStatuses.NoSet = 0 , because the default value for an Int32 is 0).

Good luck.

手心的温暖 2024-10-22 12:05:43

Parvs 解决方案让我走上了正轨,但我做了一些细微的调整。

private string _EnumType;
private EnumType _Type;

//*********************************************
//*********************************************
public string EnumType
{
    get { return _Type.ToString(); }
    set
        {
            _EnumType = value;
            try
            {
                _Type = (EnumType)Enum.Parse(typeof(EnumType), value);     
            }
            catch (Exception)
            {
                _EnumType = "Undefined";
                _Type = [mynamespace].EnumType.Undefined;                  
            }                        
        }
    }

Parvs solution put me on the right track but I had some minor adjustments.

private string _EnumType;
private EnumType _Type;

//*********************************************
//*********************************************
public string EnumType
{
    get { return _Type.ToString(); }
    set
        {
            _EnumType = value;
            try
            {
                _Type = (EnumType)Enum.Parse(typeof(EnumType), value);     
            }
            catch (Exception)
            {
                _EnumType = "Undefined";
                _Type = [mynamespace].EnumType.Undefined;                  
            }                        
        }
    }
看春风乍起 2024-10-22 12:05:43

我遇到了类似的问题,并实现了一个通用的对象扁平化器/重构器 API,它将把复杂的实体扁平化为扁平的 EntityProperty 字典,并使它们可以以 DynamicTableEntity 的形式写入表存储。

然后,相同的 API 将从 DynamicTableEntityEntityProperty 字典中重新组合整个复杂对象。

这与您的问题相关,因为 ObjectFlattenerRecomposer API 支持展平通常不可写入 Azure 表存储的属性类型,例如 EnumTimeSpan、所有 Nullable 类型、ulonguint,将它们转换为可写的 EntityProperties。

API 还处理从扁平化 EntityProperty 字典到原始复杂对象的转换。客户端需要做的就是告诉 API,我有一个刚刚从 Azure 表中读取的 EntityProperty 字典(以 DynamicTableEntity.Properties 的形式),您可以将其转换为以下对象吗这个特定类型。 API 将重构完整的复杂对象及其所有属性,包括“Enum”属性及其原始正确值。

所有这些原始对象的扁平化和重组对于客户端(API 用户)来说都是透明的。客户端不需要向 ObjectFlattenerRecomposer API 提供有关其想要写入的复杂对象的任何架构或任何知识,只需将对象作为“对象”传递给 API 即可对其进行扁平化。当将其转换回来时,客户端只需要提供它想要将扁平化 EntityProperty 字典转换为的实际对象类型。 API 的通用 ConvertBack 方法将简单地重构 Type T 的原始对象并将其返回给客户端。

请参阅下面的用法示例。这些对象不需要实现任何接口(如“ITableEntity”)或从特定基类继承。他们不需要提供一组特殊的构造函数。

博客: https://doguarslan.wordpress.com/2016/02/03/writing-complex-objects-to-azure-table-storage/

Nuget 包: https://www.nuget.org/packages/ObjectFlattenerRecomposer/

用法:

//Flatten object (ie. of type Order) and convert it to EntityProperty Dictionary
 Dictionary<string, EntityProperty> flattenedProperties = EntityPropertyConverter.Flatten(order);

// Create a DynamicTableEntity and set its PK and RK
DynamicTableEntity dynamicTableEntity = new DynamicTableEntity(partitionKey, rowKey);
dynamicTableEntity.Properties = flattenedProperties;

// Write the DynamicTableEntity to Azure Table Storage using client SDK

//Read the entity back from AzureTableStorage as DynamicTableEntity using the same PK and RK
DynamicTableEntity entity = [Read from Azure using the PK and RK];

//Convert the DynamicTableEntity back to original complex object.
 Order order = EntityPropertyConverter.ConvertBack<Order>(entity.Properties);

I have come across a similar problem and have implemented a generic object flattener/recomposer API that will flatten your complex entities into flat EntityProperty dictionaries and make them writeable to Table Storage, in the form of DynamicTableEntity.

Same API will then recompose the entire complex object back from the EntityProperty dictionary of the DynamicTableEntity.

This is relevant to your question because the ObjectFlattenerRecomposer API supports flattening property types that are normally not writeable to Azure Table Storage like Enum, TimeSpan, all Nullable types, ulong and uint by converting them into writeable EntityProperties.

The API also handles the conversion back to the original complex object from the flattened EntityProperty Dictionary. All that the client needs to do is to tell the API, I have this EntityProperty Dictionary that I just read from Azure Table (in the form of DynamicTableEntity.Properties), can you convert it to an object of this specific type. The API will recompose the full complex object with all of its properties including 'Enum' properties with their original correct values.

All of this flattening and recomposing of the original object is done transparently to the client (user of the API). Client does not need to provide any schema or any knowledge to the ObjectFlattenerRecomposer API about the complex object that it wants to write, it just passes the object to the API as 'object' to flatten it. When converting it back, the client only needs to provide the actual type of object it wants the flattened EntityProperty Dictionary to be converted to. The generic ConvertBack method of the API will simply recompose the original object of Type T and return it to the client.

See the usage example below. The objects do not need to implement any interface like 'ITableEntity' or inherit from a particular base class either. They do not need to provide a special set of constructors.

Blog: https://doguarslan.wordpress.com/2016/02/03/writing-complex-objects-to-azure-table-storage/

Nuget Package: https://www.nuget.org/packages/ObjectFlattenerRecomposer/

Usage:

//Flatten object (ie. of type Order) and convert it to EntityProperty Dictionary
 Dictionary<string, EntityProperty> flattenedProperties = EntityPropertyConverter.Flatten(order);

// Create a DynamicTableEntity and set its PK and RK
DynamicTableEntity dynamicTableEntity = new DynamicTableEntity(partitionKey, rowKey);
dynamicTableEntity.Properties = flattenedProperties;

// Write the DynamicTableEntity to Azure Table Storage using client SDK

//Read the entity back from AzureTableStorage as DynamicTableEntity using the same PK and RK
DynamicTableEntity entity = [Read from Azure using the PK and RK];

//Convert the DynamicTableEntity back to original complex object.
 Order order = EntityPropertyConverter.ConvertBack<Order>(entity.Properties);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文