“Where”方法不能遵循“选择”方法或不支持

我为什么得到:

“Where”方法不能遵循“选择”方法或不支持。 尝试根据支持的方法编写查询,或在调用不支持的方法之前调用’AsEnumerable’或’ToList’方法。

…使用WHERE子句时,比如调用时:

XrmServiceContext.CreateQuery().Project().To().Where(p => p.FirstName == "John").First(); 

这有效:

 XrmServiceContext.CreateQuery().Project().To().First(); 

这也有效:

 XrmServiceContext.CreateQuery().Where(p => p.FirstName == "John").First(); 

我正在使用AutoMapper QueryableExtension 。

附加信息:

  • 我不想在Where子句之前调用ToList()。 我知道它会这样运作。
  • CreateQuery()返回IQueryable

这是因为您使用的任何查询提供程序都无法处理此问题。 在一般情况下,它不是无效的; 事实上,大多数查询提供程序在投影后支持过滤 某些查询提供程序不像其他查询提供程序那样健壮,或者它们表示的查询模型不如LINQ接口(或两者)灵活/强大。 因此,从C#编译器的角度来看,正确的LINQ操作可能仍然无法由查询提供程序进行翻译,因此它能做的最好就是在运行时抛出exception。

你为什么不在投影之前移动它所在的位置? 它将导致执行一个过滤和项目的单个查询:

 XrmServiceContext.CreateQuery().Where(p => p.FirstName == "John").Project().To().First(); 

查看AutoMapper的QueryableExtensions说明,它有一个示例,显示投影前的Where子句。 您需要重构代码以支持此模型,而不是在投影后放置Where子句。

  public List GetLinesForOrder(int orderId)
 {
   Mapper.CreateMap()
     .ForMember(dto => dto.Item,conf => conf.MapFrom(ol => ol.Item.Name);

  使用(var context = new orderEntities())
   {
     return context.OrderLines.Where(ol => ol.OrderId == orderId)
             的.project()向()ToList()。;
   }
 }

鉴于Dynamic CRM的LINQ提供程序的局限性,您不应期望AutoMapper必须正确获取LINQ查询。

这个设计背后有一个逻辑。 作为开发人员,您可以创建一个工作Where子句。 然后让AutoMapper的Project().To()定义select语句。 由于CRM的LINQ提供程序支持匿名类型,因此它应该可以正常工作。 AutoMapper中投影的目的是将从每个类检索的数据限制为仅投影到类所需的数据。 它不打算根据预计的类编写Where子句。