[英]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.