为什么我会:
方法'Where'不能遵循'Select'方法或不是 支持的。尝试根据支持的方法或调用编写查询 调用不支持之前的'AsEnumerable'或'ToList'方法 方法
...使用WHERE子句时,比如调用时:
XrmServiceContext.CreateQuery<Contact>().Project().To<Person>().Where(p => p.FirstName == "John").First();
这有效:
XrmServiceContext.CreateQuery<Contact>().Project().To<Person>().First();
这也有效:
XrmServiceContext.CreateQuery<Contact>().Where(p => p.FirstName == "John").First();
我正在使用AutoMapper QueryableExtension。
其他信息:
CreateQuery<TEntity>()
返回IQueryable<TEntity>
。答案 0 :(得分:2)
这是因为您使用的任何查询提供程序都无法处理此问题。在一般情况下,它不是无效的;事实上,大多数查询提供者做支持过滤后的过滤。某些查询提供程序不像其他查询提供程序那样健壮,或者它们表示的查询模型不如LINQ接口(或两者)灵活/强大。因此,从C#编译器的角度来看,LINQ操作可能仍然无法由查询提供程序进行翻译,因此它能做的最好就是在运行时抛出异常。
答案 1 :(得分:0)
为什么不在投影前移动它所在的位置?它将导致执行一个过滤和项目的单个查询:
XrmServiceContext.CreateQuery<Contact>().Where(p => p.FirstName == "John").Project().To<Person>().First();
答案 2 :(得分:0)
查看AutoMapper's instructions for the QueryableExtensions它有一个示例,显示投影前的Where子句。您需要重构代码以支持此模型,而不是在投影后放置Where
子句。
public List GetLinesForOrder(int orderId) { Mapper.CreateMap() .ForMember(dto => dto.Item, conf => conf.MapFrom(ol => ol.Item.Name); using (var context = new orderEntities()) { return context.OrderLines.Where(ol => ol.OrderId == orderId) .Project().To().ToList(); } }
鉴于Dynamic CRM的LINQ提供程序的局限性,您不应期望AutoMapper必须正确获取LINQ查询。
这种设计背后有一个逻辑。作为开发人员,您可以创建一个有效的Where
子句。然后,让AutoMapper的Project().To()
定义select
语句。由于CRM的LINQ提供程序支持匿名类型,因此它应该可以正常工作。 AutoMapper中投影的目的是将从每个类检索的数据限制为仅投影到类所需的数据。它不打算基于预计的类来编写Where
子句。