对具有动态字段的实体的 OData查询



我使用OData在一个动态模型上。MyObject数据以两种不同的方式存储在数据库中-在主MyObject表中和在键/值对的辅助表中。二级表允许的字段名存储在第三个表中。使用PIVOT,我可以检索包含静态和动态字段的MyObject项目列表。如果我将构建器的EntitySet分配给MyObject模型,我还可以在任何静态字段上使用$top,$filter$orderby。但是,我无法将$filter$orderby与任何动态字段一起使用,因为它们不存在于MyObject模型上。

我尝试使用DynamicObjectExpandoObject创建一个动态模型,并使用代替MyObject,但我仍然无法运行$filter$orderby上的任何字段,以前没有定义。在每一种情况下,代码在到达控制器之前都会失败,并传递一条消息,即该字段在分配给构建器的任何模型上都不存在。因为我需要考虑到不同的用户有不同的字段,以及允许自动包含新字段,所以我不知道如何设置。

Startup.csConfigureServices中,我有以下内容:

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实体进行任何查询之前。

提前感谢!

我设法通过删除MyObjectControllerGet方法上的EnableQuery属性来实现这一点。根据文档,此属性可防止恶意查询。这似乎也阻止了在$filter$orderby中使用任何额外的动态字段。

我不知道删除这个属性是不是一个好主意,所以我仍然愿意接受关于如何处理这个问题的任何其他建议。

您可以查看OData的Open Types。如果你的实体是这样定义的,你可以用正常的[EnableQuery]属性来查询你的动态属性。

最新更新