Select the objects where the ID in the int array are WCF, LINQ data services

I would like to return a set of objects that have an ID that is contained in a list or array of identifiers using LINQ and Data Services. I know how this happens with LinqToEF, but I don’t understand how this happens with Data Services or using OData usage conventions.

My thought is that I would do something like:

int[] intArray = {321456, 321355, 218994, 189232}; var query = (from data in context.Entity where intArray.contains(data.ID) select data); 

Is there a way to do work with Data Services / OData? I know that I could hack it using Service Operation, but I would prefer not to.

Greetings.

+6
c # linq wcf-data-services
source share
3 answers

Currently, OData (the base protocol) does not support the Contains operation. So why the client library does not translate the above request. People basically use two ways to overcome this limitation: 1) Use service operations, as you noted. 2) Create a dynamic where clause that uses simple comparisons to compare the value with each element in the array. Therefore, if the array contains 1, 2, 3, where will be data.ID == 1 || data.ID == 2 || data.ID == 3 Solution # 2 is nice, because the client side is only changing. The disadvantage is that it only works for small arrays. If the array contains too many elements, the expression becomes too long, which leads to all problems. Solution # 1 does not have a size problem, but you need to provide an operation on the server.

+8
source share

Here is my implementation of the WhereIn () method for filtering an IQueryable collection by a set of selected objects:

  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; } 

And the call to this method looks like this:

 IQueryable<Product> q = context.Products.ToList(); var SelectedProducts = new List<Product> { new Product{Id=23}, new Product{Id=56} }; ... // Collecting set of product id var selectedProductsIds = SelectedProducts.Select(p => p.Id).ToList(); // Filtering products q = q.WhereIn(c => c.Product.Id, selectedProductsIds); 
+3
source share

Thank you, you helped me a lot :) :)

I did it as Vitek Karas said.

1) Download dynamic query library Check link

No need to read, just download the dynamic query library

2) Check out the DynamicQuery project. In it you will find the Dynamic.cs class. Copy it to your project

3) Create your own project (if you use silverlight, an error will appear that says ReaderWriterLock was not found. Do not be afraid. Just comment or delete lines that make mistakes (6 or 7 lines that make mistakes in total))

4) All you need now to write a request Example: ordersContext.CLIENTS.Where(" NUMCLI > 200 || NUMCLI < 20");

Done. If you need to use the Contains method, you just have to write a method that iterates over your array and returns the string that your query will use.

  private string MyFilter() { string st = ""; foreach(var element in myTab) { st = st + "ThePropertyInTheTable =" + element + "||"; } return st; } 

I hope you understand me and I helped someone :)

0
source share

All Articles