0

これは実際には EF Code First に関する質問ですが、OData のコンテキストによって違いが生じることがあります。質問は簡単です。基になる SQL Server テーブル/ビューには、(代理) 主キーとして Identity 列があります。また、ユーザーが使い慣れた一意の識別子を表す「コード」フィールドもあります。簡単な例: CarModel: Id = 3, Code = 'Ford'; データ注釈を使用して、ナビゲーション キーとして「コード」フィールドを使用してナビゲートする EF モードと OData を正常に作成しました。基になるテーブル/ビューにはそれらの列にインデックスがあるため、これは許容されます。しかし、Id 列をキーとして、モデルのナビゲーション プロパティとして使用したいのですが、応答には表示されません。おそらく、これが OData 部分の違いです。複雑な傍受や応答の再形成を行いたくないからです。列を「プライベート」または「内部」に設定すると、モデルの生成中にエラーがスローされます:「テーブル X にキーが定義されていません」

EF モデルで ID 列を定義することはできますが、それを OData エンティティ/応答の一部にすることはできませんか?


編集:

したがって、以下の私のコメントはまだ有効です。これは、ID/キー列にとっては良い考えではなく、それらを「隠す」ことでモデルを正しくコンパイルすることもできません。ただし、@mreyeros からのいくつかのリンクと、Vitek Karas からの social.msdn への投稿のおかげで、ここにいくつかのメモがあります。System.Data.Services 名前空間にはIgnorePropertiesAttribute. モデルのプロパティを「非表示」にすることができます。ただし、Vitek が言うように、現在は ReflectionProvider でのみ機能し、EF では機能しません。(また、NuGet マネージド リリースを使用している場合は、正しいライブラリを参照していることを確認する必要があります。

つまり、流暢な構成 APIEF/OData で機能します。

modelBuilder.Entity<Foo>().Ignore(f => f.Password);

ただし、応答でプロパティを非表示にするだけでなく、モデルとデータベースからも非表示にします (読み取り専用のクエリ モデルでは問題ない場合があります)。したがって、ナビゲーション キーを非表示としてマークすると、モデルはコンパイルされません。また、他のプロパティを非表示としてマークしても、それを QueryInterceptor で参照すると、例外がスローされます。

4

2 に答える 2

2

必要なことは、元のエンティティの射影されたサブセットを返す odata コントローラーを作成することです。

//in WebApi Config Method
config.MapHttpAttributeRoutes();

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<FullEntity>("FullData");
builder.EntitySet<SubsetEntity>("SubsetData");
config.Routes.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());


config.Routes.MapHttpRoute(
  name: "DefaultApi",
  routeTemplate: "api/{controller}/{action}/{id}",
  defaults: new { id = RouteParameter.Optional, action = "GET" }
);
SetupJsonFormatters();
config.Filters.Add(new UncaughtErrorHandlingFilterAttribute());

...次に、2 つの Odata コントローラーを用意し、1 つは FullData 用、もう 1 つは SubsetData 用 (異なるセキュリティを使用)、

namespace myapp.Web.OData.Controllers
{
    public class SubsetDataController : ODataController
    {
        private readonly IWarehouseRepository<FullEntity> _fullRepository;
        private readonly IUserRepository _userRepository;

        public SubsetDataController(
            IWarehouseRepository<fullEntity> fullRepository,
            IUserRepository userRepository
            )
        {
            _fullRepository = fullRepository;
            _userRepository = userRepository;
        }

public IQueryable<SubsetEntity> Get()
        {
            Object webHostHttpRequestContext = Request.Properties["MS_RequestContext"];
            System.Security.Claims.ClaimsPrincipal principal =
                (System.Security.Claims.ClaimsPrincipal)
                    webHostHttpRequestContext.GetType()
                        .GetProperty("Principal")
                        .GetValue(webHostHttpRequestContext, null);
            if (!principal.Identity.IsAuthenticated)
                throw new Exception("user is not authenticated cannot perform OData query");

            //do security in here

            //irrelevant but this just allows use of data by Word and Excel.
            if (Request.Headers.Accept.Count == 0)
                Request.Headers.Add("Accept", "application/atom+xml");

            return _fullRepository.Query().Select( b=>
                    new SubsetDataListEntity
                    {
                        Id = b.Id,
                        bitofData = b.bitofData
                    }
          } //end of query
   } //end of class
于 2016-05-11T17:23:19.643 に答える
0

これが当てはまるかどうかは 100% わかりませんが、非表示にするプロパティに「ScaffoldColumn(false)」属性を適用すると、機能する可能性があります。その属性のMSDNエントリは次のとおりです。

于 2012-08-07T17:40:34.460 に答える