对具有动态字段的实体的 OData 查询
OData Queries on Entities with Dynamic Fields
我在动态模型上使用 OData。 MyObject
数据以两种不同的方式存储在数据库中 - 在主 MyObject
table 和辅助 table 中 key/value 对。辅助 table 允许的字段名称存储在第三个 table 中。使用 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
与 class 一起使用,并且可以动态更改?或者有没有办法在 EntityType
中定义可以解释动态字段的内容?当用户调用控制器时,我可以获得这些字段的列表 - 在需要对 MyObject
实体进行任何查询之前。
提前致谢!
我设法通过删除 MyObjectController
的 Get
方法上的 EnableQuery
属性使其工作。基于documentation,这个属性可以防止恶意查询。它似乎也在阻止在 $filter
和 $orderby
.
中使用任何额外的动态字段
我不知道删除这个属性是否是个好主意,所以我仍然愿意接受任何其他关于如何处理这个问题的建议。
我在动态模型上使用 OData。 MyObject
数据以两种不同的方式存储在数据库中 - 在主 MyObject
table 和辅助 table 中 key/value 对。辅助 table 允许的字段名称存储在第三个 table 中。使用 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
与 class 一起使用,并且可以动态更改?或者有没有办法在 EntityType
中定义可以解释动态字段的内容?当用户调用控制器时,我可以获得这些字段的列表 - 在需要对 MyObject
实体进行任何查询之前。
提前致谢!
我设法通过删除 MyObjectController
的 Get
方法上的 EnableQuery
属性使其工作。基于documentation,这个属性可以防止恶意查询。它似乎也在阻止在 $filter
和 $orderby
.
我不知道删除这个属性是否是个好主意,所以我仍然愿意接受任何其他关于如何处理这个问题的建议。