我有一个包含大型代码库的项目,该代码库使用内部数据访问层来处理数据库。但是,我们希望支持OData访问系统。我对C#中的表达式树很满意。我如何得到我可以在这里解析的东西,以获得他们实际查询的结构?
有没有办法从这个东西中获取AST,我可以变成sql代码?
答案 0 :(得分:0)
基本上,您需要实现自己的Query Provider,它知道如何将表达式树转换为基础查询。
控制器方法的简化版本是:
[ODataRoute("foo")]
public List<Foo> GetFoo(ODataQueryOptions<Foo> queryOptions)
{
var queryAllFoo = _myQueryProvider.QueryAll<Foo>();
var modifiedQuery = queryOptions.ApplyTo(queryAllFoo);
return modifiedQuery.ToList();
}
然而!
答案 1 :(得分:0)
您可以使用ODataQueryOptions<T>
获取$filter
和$orderby
查询选项的抽象语法树。 ($skip
和$top
也可用作已解析的整数。)由于您不需要/想要LINQ支持,您可以简单地将AST传递给存储库方法,然后访问存储库方法ASTs构建适当的SQL存储过程调用。你不会致电ODataQueryOptions.ApplyTo
。这是一个草图:
public IEnumerable<Thing> Get(ODataQueryOptions<Thing> opts)
{
var filter = opts.Filter.FilterClause.Expression;
var ordering = opts.OrderBy.OrderByClause.Expression;
var skip = opts.Skip.Value;
var top = opts.Top.Value;
return this.Repository.GetThings(key, filter, ordering, skip, top);
}
请注意,上面的filter
和ordering
是Microsoft.OData.Core.UriParser.Semantic.SingleValueNode
的实例。该类有一个方便的Accept<T>
方法,但您可能不希望您的存储库直接依赖该类。也就是说,您应该使用帮助程序来生成独立于Microsoft的OData实现的中间形式。
如果这是一种常见模式,请考虑使用parameter binding,以便直接从控制器方法的参数列表中获取各种查询选项。