在应用了筛选器之后,如何向c# oData结果集添加信息?

本文关键字:结果 oData 添加 信息 筛选 应用 之后 | 更新日期: 2023-09-27 17:54:14

我正在使用c# MVC,并有一个odata驱动的视图来显示来自大表(~ 100万行)的数据。许多数据可以直接从数据库中查询和显示,但是需要重新格式化一列,以包含从另一个数据库中查找的数据。

在数据库中的所有100万行上运行这些查找太慢了,但是在返回给用户的20行上运行这些查找就可以了。我不需要对这些列进行排序或筛选。

在行已经被过滤之后,我如何运行这些查找?

一个可能的模式是:

public class LogController : System.Web.Http.OData.OdataController
{
        public IQueryable<LogResult> GetLogs(ODataQueryOptions opts)
        {
            ODataV2(Request);
            var logs = LogRepository.All();
            /* Do something here to filter out unwanted results */
            // I'll need to convert to a list if I'm going to run a foreach over it
            var logsList = logs.ToList()
            foreach (var log in logsList)
            {
                log.CalculatedProperty = ExpensiveFunction(log);
            }
            return logsList.AsQueryable();
        }
    }
}

或者也许有一种方法可以在返回给用户之前对GetLogs的输出进行后处理?或者我可以用Log的计算性质?

关键是我想运行ExpensiveFunction() 20次,而不是100万次。

在应用了筛选器之后,如何向c# oData结果集添加信息?

您可以使用一些小技巧来防止转换为列表,反之亦然:

/* Do something here to filter out unwanted results */
return logs.Select(l => {
    l.CalculatedProperty = ExpensiveFunction(log);
    return l; // or even yield return
});

我不能说这个解决方案是最好的,但在某些情况下它可能会更好一些。

可以应用QueryOption然后更新结果吗?

将返回类型更改为IHttpActionResult

var logsList = ops.ApplyTo(logs, new ODataQuerySettings()).toList();
// reform logsList
return MakeGenericResult(logsList.AsQueryable(), logsList.AsQueryable().GetType());
private IHttpActionResult Ok(object content, Type type)
{
    var resultType = typeof(OkNegotiatedContentResult<>).MakeGenericType(type);
    return Activator.CreateInstance(resultType, content, this) as IHttpActionResult;
}