gom*_*ala 6 c# linq wcf-data-services
我想使用LINQ和Data Services返回一组实体,这些实体具有包含在ID列表或数组中的ID和ID.我知道如何使用LinqToEF,但我不知道如何使用Data Services或使用OData查询约定.
我的想法是我会做类似的事情:
int[] intArray = {321456, 321355, 218994, 189232};
var query = (from data in context.Entity
where intArray.contains(data.ID)
select data);
Run Code Online (Sandbox Code Playgroud)
有没有办法使用Data Services/OData?我知道我可能会通过服务操作破解它,但我宁愿不这样做.
干杯.
目前OData(底层协议)不支持Contains操作.这就是客户端库不翻译上述查询的原因.人们基本上使用两种方法来克服这种限制:1)如你所指出的那样使用服务操作.2)动态构造一个where子句,它使用简单的比较来比较数组中每个项的值.因此,如果数组包含1,2,3,那么data.ID == 1 || data.ID == 2 || data.ID == 3#2解决方案很好,因为它只是客户端改变.缺点是,它只适用于小型阵列.如果数组包含太多项,则表达式会变得太长,从而导致各种麻烦.#1解决方案没有大小问题,但您需要在服务器上提供操作.
这是我对WhereIn()方法的实现,通过一组选定的实体来过滤IQueryable集合:
public static IQueryable<T> WhereIn<T,TProp>(this IQueryable<T> source, Expression<Func<T,TProp>> memberExpr, IEnumerable<TProp> values) where T : class
{
Expression predicate = null;
ParameterExpression param = Expression.Parameter(typeof(T), "t");
bool IsFirst = true;
// Create a comparison for each value eg:
// IN: t => t.Id == 1 | t.Id == 2
MemberExpression me = (MemberExpression) memberExpr.Body;
foreach (TProp val in values)
{
ConstantExpression ce = Expression.Constant(val);
Expression comparison = Expression.Equal(me, ce);
if (IsFirst)
{
predicate = comparison;
IsFirst = false;
}
else
{
predicate = Expression.Or(predicate, comparison);
}
}
return predicate != null
? source.Where(Expression.Lambda<Func<T, bool>>(predicate, param)).AsQueryable<T>()
: source;
}
Run Code Online (Sandbox Code Playgroud)
该方法的调用如下所示:
IQueryable<Product> q = context.Products.ToList();
var SelectedProducts = new List<Product>
{
new Product{Id=23},
new Product{Id=56}
};
...
// Collecting set of product id's
var selectedProductsIds = SelectedProducts.Select(p => p.Id).ToList();
// Filtering products
q = q.WhereIn(c => c.Product.Id, selectedProductsIds);
Run Code Online (Sandbox Code Playgroud)