如何在应用过滤器后向C#oData结果集添加信息

时间:2016-07-01 10:23:02

标签: c# performance linq odata

我正在使用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万次。

2 个答案:

答案 0 :(得分:0)

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

/* Do something here to filter out unwanted results */

return logs.Select(l => {
    l.CalculatedProperty = ExpensiveFunction(log);

    return l; // or even yield return
});

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

答案 1 :(得分:0)

您可以应用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;
}