Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从FilterQueryOption获取Linq表达式引发CLR异常_C#_Linq_Odata_Entity Framework 6_Linq Expressions - Fatal编程技术网

C# 从FilterQueryOption获取Linq表达式引发CLR异常

C# 从FilterQueryOption获取Linq表达式引发CLR异常,c#,linq,odata,entity-framework-6,linq-expressions,C#,Linq,Odata,Entity Framework 6,Linq Expressions,我们有一个基于 我们需要解析这个字符串,并在第一个生成的EntityFramework6模型上执行WHERE子句 步骤: 使用Breeze EdmBuilder nuget软件包将数据模型DbContext转换为IEdmlModel 使用此EdmModel创建一个ODataQueryContext 使用ODataQueryContext和筛选器字符串创建一个FilterQueryOption 此时,我们有一个FilterQueryOption对象,其中包含一个格式良好的表达式树 我们的问题是当我

我们有一个基于

我们需要解析这个字符串,并在第一个生成的EntityFramework6模型上执行WHERE子句

步骤:

  • 使用Breeze EdmBuilder nuget软件包将数据模型
    DbContext
    转换为
    IEdmlModel
  • 使用此
    EdmModel
    创建一个
    ODataQueryContext
  • 使用
    ODataQueryContext
    和筛选器字符串创建一个
    FilterQueryOption
  • 此时,我们有一个
    FilterQueryOption
    对象,其中包含一个格式良好的表达式树

    我们的问题是当我们将这个表达式树转换为Linq(在EF Where子句中使用)时

    我们在互联网上找到了这种转换方法: (内部异常消息)

    静态私有表达式GetFilterExpression(FilterQueryOption筛选器)
    {
    var enumerable=enumerable.Empty().AsQueryable();
    var param=表达式参数(typeof(Countries));
    if(过滤器!=null)
    {
    enumerable=(IQueryable)filter.ApplyTo(enumerable,新的ODataQuerySettings());
    //例外:查询选项未绑定到任何CLR类型。只有绑定到CLR类型的查询选项才支持“ApplyTo”。
    var mce=enumerable.Expression作为MethodCallExpression;
    如果(mce!=null)
    {
    var quote=mce.Arguments[1]作为一元表达式;
    如果(引号!=null)
    {
    返回quote.Operand作为表达式;
    }
    }
    }
    返回表达式.Lambda(表达式.Constant(true),param);
    }
    

    有人能帮忙吗?

    就像在评论中说的,我需要使用
    typeof(Countries)
    来构建
    ODataQueryContext

    之后抛出的异常是“TestApiRest.Countries not found”

    因此,我打开了edmx文件属性并更改了名称空间以匹配我的项目名称空间 (这是TestApiRest模型,我将其更改为TestApiRest)

    这是我的
    ODataFilterConverter
    类,它与我的第一个小测试一起工作:odataString=“Id eq 2”

    公共类ODataFilterConverter
    {
    私有只读IEDMM模型m_模型;
    公共ODataFilterConverter(TestRestApiEntities db)
    {
    m_model=db.GetEdm();//*Breeze实验室:EdmBuilder*
    }
    公共表达式转换(字符串转换)
    {
    var filterQueryOption=GetFilterQueryOption(GetQueryContext(),odataString);
    返回GetFilterExpression(filterQueryOption);
    }
    私有ODataQueryContext GetQueryContext()
    {
    返回新的ODataQueryContext(m_model,typeof(T));
    }
    私有筛选器查询选项GetFilterQueryOption(ODataQueryContext queryContext,字符串筛选器)
    {
    返回新的FilterQueryOption(filter,queryContext);
    }
    静态私有表达式GetFilterExpression(FilterQueryOption筛选器)
    {
    var enumerable=enumerable.Empty().AsQueryable();
    var param=表达式参数(typeof(T));
    if(过滤器!=null)
    {
    enumerable=(IQueryable)filter.ApplyTo(enumerable,新的ODataQuerySettings());
    var mce=enumerable.Expression作为MethodCallExpression;
    如果(mce!=null)
    {
    var quote=mce.Arguments[1]作为一元表达式;
    如果(引号!=null)
    {
    返回quote.Operand作为表达式;
    }
    }
    }
    返回表达式.Lambda(表达式.Constant(true),param);
    }
    }
    
    问题不在于
    过滤器查询选项
    edm模型未正确映射实体。尝试将
    GetQueryContext
    中的第3行更改为使用typeof(Country)而不是IEdmEntityType。这不适用于OData V4
    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);
    }
    
      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);
        }
      }