简体   繁体   English

在无类型实体上应用查询选项

[英]Applying query options on typeless entity

How can I apply the query options on a non clr type. 如何将查询选项应用于非clr类型。 The .ApplyTo method is throwing an error when I'm using it. 我使用.ApplyTo方法时会引发错误。

Error: 错误:

"The query option is not bound to any CLR type. 'ApplyTo' is only supported with a query option bound to a CLR type." “查询选项未绑定到任何CLR类型。只有绑定到CLR类型的查询选项才支持'ApplyTo'。”

var x = (EdmCollectionType)Request.GetODataPath().EdmType;
ODataQueryContext queryContext = new ODataQueryContext(Request.GetEdmModel(), x.ElementType.Definition);
ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, Request);

//codes.....

queryOptions.ApplyTo(Products);

Just as the error said, the query options can't be applied on a non clr type now. 就像错误所言,查询选项现在不能应用于非clr类型。

It is because now webapi need the clr type to generate linq expression for query options. 这是因为现在webapi需要clr类型来生成查询选项的linq表达式。

However you can implement the ApplyTo function on a non clr type yourself with the raw values in the query options: 但是,您可以使用查询选项中的原始值自己在非clr类型上实现ApplyTo函数:

queryOptions.Filter.RawValue
queryOptions.OrderBy.RawValue
...
ODataQueryContext queryContext = new ODataQueryContext(Request.GetEdmModel(), x.ElementType.Definition);

In the above line, we need to explicitly pass the Class Type obj to ODataQueryContext. 在上一行中,我们需要将Class Type obj显式传递给ODataQueryContext。 Let's assume a type named A which has been created at runtime. 假设在运行时创建了一个名为A的类型。

Type a = //Get the type at runtime ;
ODataQueryContext queryContext = new ODataQueryContext(Request.GetEdmModel(), a);

This should resovle the exception. 这应该解决异常。

Now, come to ApplyTo() we can pass an instance of type A to it. 现在,来到ApplyTo(),我们可以将类型A的实例传递给它。

object instance = Activator.CreateInstance(a);
odataQuerySetting.ApplyTo(instance,, new ODataQuerySettings() { });

However, we would like to run ApplyTo() against a list of objects as well as one instance. 但是,我们希望针对对象列表和一个实例运行ApplyTo()。 Array class could help us to accomplish this. 数组类可以帮助我们完成此任务。 Suppose we need to create 10 instances: 假设我们需要创建10个实例:

Array values = Array.CreateInstance(a, 10);
for (int i = 0; i < 10; i++)
        {
            values.SetValue(Activator.CreateInstance(t), i);
        }

Needless to say that we can add properties to our instances as we would like to and then pass it to SetValue(). 不用说,我们可以根据需要向实例添加属性,然后将其传递给SetValue()。 Finally, the ApplyTo() can be executed against our list as follow: 最后,可以针对我们的列表执行ApplyTo(),如下所示:

  queryOptions.ApplyTo(values.AsQueryable());

Note: if you get the status:406 then one possible cause could be the JsonFormat. 注意:如果获得状态:406,则可能的原因之一可能是JsonFormat。 use a custom MediaTypeFormatter to resolve that. 使用自定义MediaTypeFormatter可以解决该问题。

I hope that this might help someone. 我希望这可以帮助某人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM