簡體   English   中英

如何在OData的EF Code First模型中隱藏標識列

[英]How to hide identity column in EF Code First model for OData

這確實是EF Code First問題,但有時OData的上下文會有所不同。 問題很簡單。 我們的基礎SQL Server表/視圖具有“標識”列作為(代理)主鍵。 它們還具有一個“代碼”字段,代表用戶熟悉的唯一標識符。 簡單示例:CarModel:Id = 3,代碼='Ford'; 我已經成功創建了EF模式和OData,以使用“代碼”字段作為導航鍵,使用了數據注釋來進行導航,並且基礎表/視圖在這些列上都有索引,因此可以接受。 但是我真的很想把Id列作為鍵,並作為模型中的Navigation屬性,但不要在響應中顯示它。 也許這就是OData部分與眾不同的地方,因為我不希望對響應進行任何復雜的攔截和重塑。 將列設置為“私有”甚至“內部”會在模型生成過程中引發錯誤:“表X未定義鍵”

是否可以在EF模型中定義一個身份列,但不將其作為OData實體/響應的一部分?


編輯:

因此,我在下面的評論仍然有效。 對於身份/關鍵字列來說,這既不是一個好主意,也不是“隱藏”它們使模型能夠正確編譯。 但是,感謝@mreyeros的一些鏈接以及Vitek Karas的social.msdn帖子,這里有一些注意事項。 System.Data.Services命名空間具有IgnorePropertiesAttribute 它允許“隱藏”模型中的屬性。 但是,正如Vitek所說,它目前僅與ReflectionProvider一起使用,而不與EF一起使用。 (如果您使用的是NuGet托管版本,則需要確保引用的庫正確。

也就是說,流暢的配置API 可以在EF / OData中運行:

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

但是,它不僅在響應中隱藏了一個屬性,而且還在模型和數據庫中隱藏了它(對於只讀查詢模型可能是可以的)。 因此,如果將導航鍵標記為隱藏,則該模型將無法編譯。 並且,如果您將任何其他屬性標記為隱藏,但在QueryInterceptor中引用了該屬性,則將引發異常。

我不是100%確定是否是這種情況,但是,如果將“ ScaffoldColumn(false)”屬性應用於要隱藏的屬性,則可能會起作用。 這是該屬性的MSDN條目

您需要做的是創建一個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());

...然后有兩個Odata控制器,一個用於FulLData,一個用於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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM