是否可以使用 ASP.NET Web APi OData 进行类似操作:
List<string> customersTitles = Odata.OrdersService.Select(o=>o.CustomerTitle).Distinct().ToList();
List<Customer> customers = Odata.CustomerService.Where(m => customersTitles .Contains(m.CustomerTitle))
获取错误:
Error translating Linq expression to URI: The expression value(System.Collections.Generic.List`1[System.String]).Contains([10007].CustomerTitle) is not supported.}
应用程序接口(interface):
public class CustomerController : EntitySetController<Customer, int>
{
[Queryable]
public override IQueryable<Customer> Get()
{
Expression filter = this.QueryOptions.Filter.ToExpression<Customer>();
return db.Query<Customer>(filter as Expression<Func<Customer, bool>>);
}
}
最佳答案
Contains 构造不受 URI 支持,因为存在于客户端的字符串列表不是服务器端资源。
Linq2Sql Provider 对 Contains 有一个固有的翻译,它被翻译成 SQL 的 IN 子句。
OData 不支持这样的转换。您需要构建的是使用所有 Title 值的 where 子句的扩展查询列表:
因为这行不通:
List<Customer> customers = Odata.CustomerService.Where(m => customersTitles .Contains(m.CustomerTitle))
扩展查询选项帮助我们构建如下查询:
List<Customer> customers = Odata.CustomerService.Where(m => m.CustomerTitle == customerTitles[0] || m.CustomerTitle == customerTitles[1]); // and so on
这是构建过滤器的代码:
var titleFilterList = customerTitles.Select(title => String.Format("(CustomerTitle eq {0})", title));
var titleFilter = String.Join(" or ", titleFilterList);
var customers = Odata.CustomerService.AddQueryOption("$filter", titleFilter).Execute().ToList(); // you may have to cast this.
还有另一种选择,可以使用很好的扩展方法并构建基于动态表达式的谓词,以强类型方式执行相同的操作。按照此处的步骤操作:
关于c# - Odata 在调用时转换 Linq 表达式时出错包含,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22893020/