17

POCO データ モデルを使用して WCF データ サービスを手動で構築しようとしていますが、enum値を適切に公開する方法がわかりません。次のような単純なモデルを想定します。

public class Order
{
   public int ID {get; set;}
   public string Description {get; set;}
   public OrderStatus Status {get; set;}
}

public enum OrderStatus
{
   New,
   InProcess,
   Complete
}

OrderStatusOData WCF データ サービスを介して、プロパティ内の貴重な情報をどのように公開しますか?

何もしない場合、Data Service は実行時エラーを生成します (enum は無効なプロパティです)。少なくともエラーを解決する唯一の答えは、次のenumようにプロパティを無視することです。

[System.Data.Services.IgnoreProperties("Status")]
public class Order ...

これは機能しますが、サービス層から貴重な情報を「省略」する必要があります。WCF Data Services で列挙値を操作するための他のオプションはありますか?

編集:これはWCF Data Services (別名 Astoria)であることに注意してください。これは生の WCF サービスではありません。その場合、答えはより明確になります。

4

6 に答える 6

16

列挙型は現在、WCF Data Services ではサポートされていません (OData プロトコルでもサポートされていません)。一般的な回避策は、文字列と定数値、または整数値と定数値を使用することです。

于 2010-08-26T00:59:54.767 に答える
5

たぶん、以下の回避策でそれを「ごまかす」ことができます:

[System.Data.Services.IgnoreProperties("Status")]
public class Order
{
   public int ID {get; set;}
   public string Description {get; set;}
   public OrderStatus Status {get; set;}
   public int StatusValue
   {
      get
      {
           return (int)this.Status;
      }
      set
      {
          // Add validation here
          this.Status = (OrderStatus)value;
      } 
   }
}

public enum OrderStatus
{
   New,
   InProcess,
   Complete
}
于 2010-08-26T14:07:25.717 に答える
5

フォローアップとして、「ラッパー」アプローチが最終的に機能しました。基本的に、Data Service でenumプリミティブ値をラップして返す小さなクラスが作成されます。int

[IgnoreProperties("EnumValue")]
public class OrderStatusWrapper
{
    private OrderStatus _t;

    public int Value
    {
        get{ return (int)_t; }
        set { _t = (OrderStatus)value; }
    }

    public OrderStatus EnumValue
    {
        get { return _t; }
        set { _t = value; }
    }

    public static implicit operator OrderStatusWrapper(OrderStatus r)
    {
        return new OrderStatusWrapper { EnumValue = r };
    }

    public static implicit operator OrderStatus(OrderStatusWrapper rw)
    {
        if (rw == null)
            return OrderStatus.Unresolved;
        else
            return rw.EnumValue;
    }
}  

enumこれは主に、EF4 の制限を回避するために与えられたアドバイスに基づいています。

http://blogs.msdn.com/b/alexj/archive/2009/06/05/tip-23-how-to-fake-enums-in-ef-4.aspx

このテクニックが、後に続く他の人たちに役立つことを願っています。

于 2010-08-27T21:55:57.057 に答える
2

次のように、DataContractのシリアル化を想定します。

[DataContract]
public class Order
{
   [DataMember]
   public int ID {get; set;}
   [DataMember]
   public string Description {get; set;}
   [DataMember]
   public OrderStatus Status {get; set;}
}

[DataContract]
public enum OrderStatus
{
    [EnumMember]
    New,
    [EnumMember]
    InProcess,
    [EnumMember]   
    Complete
}
于 2010-08-25T21:18:40.510 に答える
0

独自のQueryPrividerを作成する必要があります

    public object GetPropertyValue(object target, ResourceProperty resourceProperty)
    {
        object result = null;
        PropertyInfo info = target.GetType().GetProperty(resourceProperty.Name);
        if (info != null)
            result = info.GetValue(target, null);
        if (result is Enum)
            return Convert.ToInt32(result);
        return result;
    }


    public ResourceType GetResourceType(object target)
    {
        ResourceType result = null;
        Type tp = target.GetType();
        if (tp.IsEnum)
        {
            result =  ResourceType.GetPrimitiveResourceType(typeof(Int32));
            return result;
        }
        ....
        return result;
    }
于 2011-12-09T09:26:33.880 に答える
0

列挙型をデータコントラクトにする必要があります。

例については、こちらをご覧ください:http: //consultingblogs.emc.com/merrickchaffer/archive/2007/04/03/Passing-Enum-values-into-WCF-Service-operations.aspx

[編集]どうやら、ここに見られるように常にそうであるとは限りません: WCFサービスとの列挙型の共有

于 2010-08-25T21:16:41.213 に答える