joe*_*net 2 asp.net-mvc asp.net-web-api
此示例的代码已被简化。
该查询实际上是从服务返回的,这就是为什么我更喜欢以这种方式编写该方法。
[HttpGet]
public PageResult<ExceptionLog> Logging(ODataQueryOptions<ExceptionLog> options)
{
var query = from o in _exceptionLoggingService.entities.ExceptionDatas
select new ExceptionLog {
ExceptionDataId = o.ExceptionDataId,
SiteId = o.SiteId,
ExceptionDateTime = o.ExceptionDateTime,
StatusCode = o.StatusCode,
Url = o.Url,
ExceptionType = o.ExceptionType,
ExceptionMessage = o.ExceptionMessage,
Exception = o.Exception,
RequestData = o.RequestData
};
var results = options.ApplyTo(query) as IEnumerable<ExceptionLog>;
var count = results.LongCount();
return new PageResult<ExceptionLog>(results, Request.GetNextPageLink(), count);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码在“results.LongCount()”上出现错误,并出现以下异常:
SqlException: The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator.
Run Code Online (Sandbox Code Playgroud)
看来我在尝试分页时遇到了异常,例如“$top=2”。如果我的查询字符串是这样的“$filter=ExceptionDataId gt 100”,则一切正常。
由于 ExceptionData (实体)与 ExceptionLog (业务模型)匹配,我可以这样做作为解决方法:
SqlException: The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator.
Run Code Online (Sandbox Code Playgroud)
但这对我来说并不完全有效,因为它有点黑客,而且我无法使用已经为我提供了 IQueryable 的服务方法。
另一件需要注意的事情是,如果 Logging 方法转换为 IQueryable,则一切正常。但我需要通过查询返回 Count,因此我必须返回 PageResult。
这是我正在使用的解决方法。我仅应用 ODataQueryOptions 中的过滤器,并手动应用“顶部”和“跳过”。
首先我创建了一些扩展方法:
using System;
using System.Collections.Generic;
using System.Linq;
namespace System.Web.Http.OData.Query
{
public static class ODataQuerySettingsExtensions
{
public static IEnumerable<T> ApplyFilter<T>(this IQueryable<T> query, ODataQueryOptions<T> options)
{
if (options.Filter == null)
{
return query;
}
return options.Filter.ApplyTo(query, new ODataQuerySettings()) as IEnumerable<T>;
}
public static IEnumerable<T> ApplyTopAndTake<T>(this IEnumerable<T> query, ODataQueryOptions<T> options)
{
IEnumerable<T> value = query;
if (options.Top != null)
{
value = value.Take(options.Top.Value);
}
if (options.Skip != null)
{
value = value.Skip(options.Skip.Value);
}
return value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我的方法如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
namespace System.Web.Http.OData.Query
{
public static class ODataQuerySettingsExtensions
{
public static IEnumerable<T> ApplyFilter<T>(this IQueryable<T> query, ODataQueryOptions<T> options)
{
if (options.Filter == null)
{
return query;
}
return options.Filter.ApplyTo(query, new ODataQuerySettings()) as IEnumerable<T>;
}
public static IEnumerable<T> ApplyTopAndTake<T>(this IEnumerable<T> query, ODataQueryOptions<T> options)
{
IEnumerable<T> value = query;
if (options.Top != null)
{
value = value.Take(options.Top.Value);
}
if (options.Skip != null)
{
value = value.Skip(options.Skip.Value);
}
return value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2250 次 |
| 最近记录: |