web-dev-qa-db-ja.com

OData読み取り専用プロパティ

ODataV4を使用したWebAPI2.2アプリケーションがあります。また、EF6.1を使用しています。

私のエンティティの1つに、計算されたプロパティがあります。

public class Person {
  public string FirstName { get; set; }
  public string LastName { get; set; }
  // Calculated Property - No setter
  public string FullName { 
    get {
      return FirstName + " " + LastName;
    }
} 

計算されたプロパティをクライアントに提供するには、ODataモデルに登録する必要があります

    public static IEdmModel GetModel()
    {
        ODataModelBuilder builder = new ODataConventionModelBuilder();
        builder.Namespace = "NavigationServices";
        builder.EntityType<Person>;   
        builder.EntityType<Person>().Property(a => a.FullName); // Calculated Property
        ....

        return builder.GetEdmModel();
    }

したがって、クライアント側でデータを取得すると、すべてのオブジェクトにCalculatedプロパティがあります。

ただし、新しい要素を作成(POST)または既存の要素を更新(PUT)しようとすると、アクションが要素を認識せず、プロパティの「setメソッド」が見つからないというエラーが生成されます。

ODataの読み取り専用プロパティ(明らかにサポートされていない)に関するいくつかの投稿を読みましたが、計算されたプロパティでODataを使用する方法が見つかりません。

この状況を克服する方法についてのアドバイスはありますか?

21
user3120088

これを行うためのソフトな方法があります。これは、注釈を使用してクライアントとサーバー間の契約を構築することです。

V4標準のコアボキャブラリー には、次のような用語があります。

<Term Name="Computed" Type="Core.Tag" DefaultValue="true" AppliesTo="Property">
    <Annotation Term="Core.Description" String="A value for this property is generated on both insert and update"/>
</Term>

Web API ODataのWebConfig.csで、このような注釈をプロパティに追加するコードを記述します。

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
var model = builder.GetEdmModel() as EdmModel;
model.SetVocabularyAnnotation(
    new EdmAnnotation(model.EntityContainer.FindEntitySet("People").EntityType().FindProperty("FullName"),
    new EdmTerm("Org.OData.Core.V1", "Computed", EdmPrimitiveTypeKind.Boolean),
    new EdmBooleanConstant(true)));

次に、データでは、次のようになります。

<Annotations Target="V4Service.Models.Person/FullName">
    <Annotation Term="Org.OData.Core.V1.Computed" Bool="true"/>
</Annotations>

上記の手順を通じて、サービスはFullNameエンティティのPersonプロパティがサービスによって計算されることをアドバタイズします。次に、POSTおよびPATCHリクエストのコントローラーメソッドで、クライアントからFullNameプロパティに送信された値を無視する独自のロジックを作成し、独自のロジックを計算できます。

使用しているクライアントがわかりません。 OData Client for .NET を使用している場合、アノテーション値の取得のサポートは次のリリースで行われます。 EdmLib を直接使用してもかまわない場合は、アノテーション値の取得サポートがすでに追加されています。

7
Yi Ding - MSFT

確かに、現時点ではODataread-only propertiesをサポートしていません。

ただし、read-only entitiesをサポートします。

または、ODataに何もしないsetterを追加して、propertyをだますことができます。

public string FullName
{ 
    get
    {
        return FirstName + " " + LastName;
    }
    set
    {
        // do nothing
    }
}

これは、entityを読み取り専用として設定する方法です。

public class Northwind : DataService<NorthwindEntities>
{
    // This method is called only once to initialize service-wide policies.
    public static void InitializeService(DataServiceConfiguration config)
    {
        config.SetEntitySetAccessRule("Customers", EntitySetRights.AllRead);
    }
}

クラス計算プロパティの代わりに、データベース計算プロパティを使用できます。

この記事では、EFとデータベースで計算されたプロパティについて説明します。 サンプルコードでこの記事と比較して見られる違いの1つは、プロパティにセッターがないことです。プライベートセットでオートアクセサーを使用するようにプロパティを設定した場合

public string FullName { 
    get;
    private set; 
}

次に、データベースに計算列として列を作成します。

ALTER TABLE dbo.Users ADD FullName AS FirstName + ' ' + LastName

追加のプラスとして、odataとLinqを使用してこのプロパティに対してクエリを実行できます。

0
Brett Feagans