我使用OData在一个动态模型上。MyObject
数据以两种不同的方式存储在数据库中-在主MyObject
表中和在键/值对的辅助表中。二级表允许的字段名存储在第三个表中。使用PIVOT,我可以检索包含静态和动态字段的MyObject
项目列表。如果我将构建器的EntitySet
分配给MyObject
模型,我还可以在任何静态字段上使用$top
,$filter
和$orderby
。但是,我无法将$filter
或$orderby
与任何动态字段一起使用,因为它们不存在于MyObject
模型上。
我尝试使用DynamicObject
或ExpandoObject
创建一个动态模型,并使用代替MyObject
,但我仍然无法运行$filter
或$orderby
上的任何字段,以前没有定义。在每一种情况下,代码在到达控制器之前都会失败,并传递一条消息,即该字段在分配给构建器的任何模型上都不存在。因为我需要考虑到不同的用户有不同的字段,以及允许自动包含新字段,所以我不知道如何设置。
在Startup.cs
ConfigureServices
中,我有以下内容:
services.AddControllers(options =>
{
options.ModelBinderProviders.RemoveType<DateTimeModelBinderProvider>();
})
.AddOData(opt =>
opt.AddRouteComponents("odata", GetEdmModel())
.Expand()
.Select()
.OrderBy()
.Filter()
.Count()
.SkipToken()
)
.AddNewtonsoftJson();
GetEdmModel
方法如下:
var builder = new ODataConventionModelBuilder();
builder.EntitySet<MyObject>("MyObjectController");
builder.EntityType<MyObject>().HasKey(k => k.Id);
return builder.GetEdmModel();
我不太熟悉设置OData。是否有一种方法来使用EntitySet
类,可以动态改变?或者在EntityType
中定义一些可以解释动态字段的方法?我可以在用户调用控制器时获得这些字段的列表-在需要对MyObject
实体进行任何查询之前。
提前感谢!
我设法通过删除MyObjectController
的Get
方法上的EnableQuery
属性来实现这一点。根据文档,此属性可防止恶意查询。这似乎也阻止了在$filter
和$orderby
中使用任何额外的动态字段。
我不知道删除这个属性是不是一个好主意,所以我仍然愿意接受关于如何处理这个问题的任何其他建议。
您可以查看OData的Open Types。如果你的实体是这样定义的,你可以用正常的[EnableQuery]
属性来查询你的动态属性。