我们有一个基于OData conventions
的过滤字符串我们需要解析这个字符串,并在我们的EntityFramework6 Model-First生成的模型上执行whereClause。
步骤:
DbContext
转换为IEdmlModel
。ODataQueryContext
创建EdmModel
。FilterQueryOption
和过滤字符串创建ODataQueryContext
。此时,我们有一个FilterQueryOption
对象,里面有一个格式良好的表达式树。
我们的问题是当我们将这个表达式树转换为Linq(在EF Where子句中使用)
时我们在互联网上发现这种方法进行转换: (里面的例外消息)
static private Expression<Func<Countries, bool>> GetFilterExpression(FilterQueryOption filter)
{
var enumerable = Enumerable.Empty<Countries>().AsQueryable();
var param = Expression.Parameter(typeof(Countries));
if (filter != null)
{
enumerable = (IQueryable<Countries>)filter.ApplyTo(enumerable, new ODataQuerySettings());
// Exception : The query option is not bound to any CLR type. 'ApplyTo' is only supported with a query option bound to a CLR type.
var mce = enumerable.Expression as MethodCallExpression;
if (mce != null)
{
var quote = mce.Arguments[1] as UnaryExpression;
if (quote != null)
{
return quote.Operand as Expression<Func<Countries, bool>>;
}
}
}
return Expression.Lambda<Func<Countries, bool>>(Expression.Constant(true), param);
}
Sample code (Solution + sql script to generate simple DB)
有人可以为此提供帮助吗?
答案 0 :(得分:0)
与Chad Carisch在评论中说的一样,我需要使用typeof(Countries)
来构建ODataQueryContext
。
之后抛出的异常是&#34; TestApiRest.Countries not found &#34;。
所以我打开edmx文件属性并更改了命名空间以匹配我的项目命名空间 (这是TestApiRestModel,我将其更改为TestApiRest)
这是我的ODataFilterConverter
课程,适用于我的第一个小测试:odataString =&#34; Id eq 2&#34;
public class ODataFilterConverter
{
private readonly IEdmModel m_model;
public ODataFilterConverter(TestRestApiEntities db)
{
m_model = db.GetEdm(); // *Breeze Labs: EdmBuilder*
}
public Expression<Func<T, bool>> Convert<T>(string odataString)
{
var filterQueryOption = GetFilterQueryOption(GetQueryContext<T>(), odataString);
return GetFilterExpression<T>(filterQueryOption);
}
private ODataQueryContext GetQueryContext<T>()
{
return new ODataQueryContext(m_model, typeof(T));
}
private FilterQueryOption GetFilterQueryOption(ODataQueryContext queryContext, string filter)
{
return new FilterQueryOption(filter, queryContext);
}
static private Expression<Func<T, bool>> GetFilterExpression<T>(FilterQueryOption filter)
{
var enumerable = Enumerable.Empty<T>().AsQueryable();
var param = Expression.Parameter(typeof(T));
if (filter != null)
{
enumerable = (IQueryable<T>)filter.ApplyTo(enumerable, new ODataQuerySettings());
var mce = enumerable.Expression as MethodCallExpression;
if (mce != null)
{
var quote = mce.Arguments[1] as UnaryExpression;
if (quote != null)
{
return quote.Operand as Expression<Func<T, bool>>;
}
}
}
return Expression.Lambda<Func<T, bool>>(Expression.Constant(true), param);
}
}