如何实例化 ODataQueryOptions
How to Instantiate ODataQueryOptions
我有一个可用的(简化的)ODataController
,方法如下。
public class MyTypeController : ODataController
{
[HttpGet]
[EnableQuery]
[ODataRoute("myTypes")]
public IQueryable<MyType> GetMyTypes(ODataQueryOptions<MyType> options)
{
return _repo.myResultsAsQueryable();
}
}
我希望能够从服务器调用此方法,为此我需要实例化一个 ODataQueryOptions
,它需要一个 ODataQueryContext
.
有一些示例说明如何执行此操作(例如,here and here) but they all seem to reference a previous version of OData. The ODataQueryContext 构造函数当前需要第三个参数(ODataPath
路径),我能找到的任何示例中均未提及。
编辑:
@snow_FFFFFF,这里有更多上下文......我意识到我可以通过 HttpClient 简单地使用 OData 端点,但我想像你说的那样直接与 IQueryable 交互。
问题是我正在开发的应用程序允许用户创建过滤器(如复杂的搜索引擎),其他用户可以将其保存并稍后调用。从 JS 客户端,他们只需按 id 查找过滤器,然后对 OData 端点发出查询,并将过滤器应用于查询字符串。这在客户端非常有效,但我希望也能在服务器端做类似的事情。
这是我想要做的,但我如何实例化 ODataPath 参数?
public IQueryable<MyType> FilterMyTypes(int filterID)
{
// lookup filter by filterID from db...
filter = "$filter=Status eq 1"; // for example...
ODataPath path = // but how can I get the path!!!
new ODataQueryContext(edmModel, typeof(MyType), path);
var uri = new HttpRequestMessage(HttpMethod.Get, "http://localhost:56339/mytypes?" + filter);
var opts = new ODataQueryOptions<MyType>(ctx, uri);
var results = new MyTypeController().GetMyTypes(opts);
}
它的另一个应用是支持动态分组,如下所示:
[HttpGet]
[Route("myTypes/{filterID:int}/groupby/{groupByFieldName}")]
public IHttpActionResult GroupMyTypes(int filterID, string groupByFieldName)
{
// For example: get all Active MyTypes and group by AssignedToUserID...
// Get the results of the filter as IQueryable...
var results = FilterMyTypes(filterID);
// group on groupByFieldName
var grouped = results.GroupBy(x => GetPropertyValue(x,groupByFieldName));
// select the groupByFieldName and the count
var transformedResults = grouped.Select(g => new { g.Key, Count = g.Count() });
return Ok(transformedResults);
}
您的 odata 控制器正在为您的数据提供 HTTP 接口,您不应该通过 HTTP 访问它(即使是从服务器)?这里有生成odata客户端代码的VS插件:
https://visualstudiogallery.msdn.microsoft.com/9b786c0e-79d1-4a50-89a5-125e57475937
或者,如果您在同一个项目中执行此操作,为什么不使用 return 可以从您的代码或控制器调用的 IQueryable 的通用方法?
更新:基于原始问题中的更多信息:
如果您在控制器方法中定义了 ODataQueryOptions,它将允许您解析调用该方法的格式良好的 Odata 查询。我在需要翻译部分 odata 查询时使用了它,因为我需要查询多个数据源以 return 最终结果。
听起来你想要一些带有非 odata 参数和选项的东西。为此,您可能需要查看自定义操作和/或函数(如果您只是 returning 数据,可能是一个函数):
更新#2:在更详细的阅读之后,我想我没有理解你的观点——我没有答案,但我会尝试一下。你不能只改造 URL 本身(而不是实例化查询选项吗?
更新#3:我想你很难让它认为它正在收到一个 odata 请求……那不是一个真正的 odata 请求.回到我原来的回答中提到的第二个选项——为什么不是你可以使用的通用方法和 odata 控制器可以使用的——像这样:
// some sort of helper class
public class HelperObject
{
public static IQueryable<MyType> GetGroupedValues(int filterID, string groupByFieldName)
{
// all your code/logic here
}
}
// your odata controller uses the helper
[HttpGet]
[Route("myTypes/{filterID:int}/groupby/{groupByFieldName}")]
public IHttpActionResult GroupMyTypes(int filterID, string groupByFieldName)
{
return Ok(HelperObject.GetGroupedValues(filterID, groupByFieldName));
}
// ... and so does your other code that wants to do the same thing
var x = HelperObject.GetGroupedValues(filterID, groupByFieldName);
当然可以。 ODataPath 是一个 ODataPathSegment 列表,它应该跟在 OData Uri spec.
之后
在Web API OData中,很容易实例化一个ODataPath,例如:
IEdmModel model = GetEdmModel();
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet(setName);
ODataPath path = new ODataPath(new EntitySetPathSegment(entitySet));
上面的path
遵循OData规范,它的odata模板为:
~/entityset
更多测试用例(代码)可以找到here
我有一个可用的(简化的)ODataController
,方法如下。
public class MyTypeController : ODataController
{
[HttpGet]
[EnableQuery]
[ODataRoute("myTypes")]
public IQueryable<MyType> GetMyTypes(ODataQueryOptions<MyType> options)
{
return _repo.myResultsAsQueryable();
}
}
我希望能够从服务器调用此方法,为此我需要实例化一个 ODataQueryOptions
,它需要一个 ODataQueryContext
.
有一些示例说明如何执行此操作(例如,here and here) but they all seem to reference a previous version of OData. The ODataQueryContext 构造函数当前需要第三个参数(ODataPath
路径),我能找到的任何示例中均未提及。
编辑: @snow_FFFFFF,这里有更多上下文......我意识到我可以通过 HttpClient 简单地使用 OData 端点,但我想像你说的那样直接与 IQueryable 交互。
问题是我正在开发的应用程序允许用户创建过滤器(如复杂的搜索引擎),其他用户可以将其保存并稍后调用。从 JS 客户端,他们只需按 id 查找过滤器,然后对 OData 端点发出查询,并将过滤器应用于查询字符串。这在客户端非常有效,但我希望也能在服务器端做类似的事情。
这是我想要做的,但我如何实例化 ODataPath 参数?
public IQueryable<MyType> FilterMyTypes(int filterID)
{
// lookup filter by filterID from db...
filter = "$filter=Status eq 1"; // for example...
ODataPath path = // but how can I get the path!!!
new ODataQueryContext(edmModel, typeof(MyType), path);
var uri = new HttpRequestMessage(HttpMethod.Get, "http://localhost:56339/mytypes?" + filter);
var opts = new ODataQueryOptions<MyType>(ctx, uri);
var results = new MyTypeController().GetMyTypes(opts);
}
它的另一个应用是支持动态分组,如下所示:
[HttpGet]
[Route("myTypes/{filterID:int}/groupby/{groupByFieldName}")]
public IHttpActionResult GroupMyTypes(int filterID, string groupByFieldName)
{
// For example: get all Active MyTypes and group by AssignedToUserID...
// Get the results of the filter as IQueryable...
var results = FilterMyTypes(filterID);
// group on groupByFieldName
var grouped = results.GroupBy(x => GetPropertyValue(x,groupByFieldName));
// select the groupByFieldName and the count
var transformedResults = grouped.Select(g => new { g.Key, Count = g.Count() });
return Ok(transformedResults);
}
您的 odata 控制器正在为您的数据提供 HTTP 接口,您不应该通过 HTTP 访问它(即使是从服务器)?这里有生成odata客户端代码的VS插件:
https://visualstudiogallery.msdn.microsoft.com/9b786c0e-79d1-4a50-89a5-125e57475937
或者,如果您在同一个项目中执行此操作,为什么不使用 return 可以从您的代码或控制器调用的 IQueryable 的通用方法?
更新:基于原始问题中的更多信息:
如果您在控制器方法中定义了 ODataQueryOptions,它将允许您解析调用该方法的格式良好的 Odata 查询。我在需要翻译部分 odata 查询时使用了它,因为我需要查询多个数据源以 return 最终结果。
听起来你想要一些带有非 odata 参数和选项的东西。为此,您可能需要查看自定义操作和/或函数(如果您只是 returning 数据,可能是一个函数):
更新#2:在更详细的阅读之后,我想我没有理解你的观点——我没有答案,但我会尝试一下。你不能只改造 URL 本身(而不是实例化查询选项吗?
更新#3:我想你很难让它认为它正在收到一个 odata 请求……那不是一个真正的 odata 请求.回到我原来的回答中提到的第二个选项——为什么不是你可以使用的通用方法和 odata 控制器可以使用的——像这样:
// some sort of helper class
public class HelperObject
{
public static IQueryable<MyType> GetGroupedValues(int filterID, string groupByFieldName)
{
// all your code/logic here
}
}
// your odata controller uses the helper
[HttpGet]
[Route("myTypes/{filterID:int}/groupby/{groupByFieldName}")]
public IHttpActionResult GroupMyTypes(int filterID, string groupByFieldName)
{
return Ok(HelperObject.GetGroupedValues(filterID, groupByFieldName));
}
// ... and so does your other code that wants to do the same thing
var x = HelperObject.GetGroupedValues(filterID, groupByFieldName);
当然可以。 ODataPath 是一个 ODataPathSegment 列表,它应该跟在 OData Uri spec.
之后在Web API OData中,很容易实例化一个ODataPath,例如:
IEdmModel model = GetEdmModel();
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet(setName);
ODataPath path = new ODataPath(new EntitySetPathSegment(entitySet));
上面的path
遵循OData规范,它的odata模板为:
~/entityset
更多测试用例(代码)可以找到here