简体   繁体   English

选择int数组中ID的实体 - WCF数据服务,LINQ

[英]Select entities where ID in int array - WCF Data Services, LINQ

I would like to return a set of entities who has and ID that is contained in a list or array of IDs using LINQ and Data Services. 我想使用LINQ和Data Services返回一组实体,这些实体具有包含在ID列表或数组中的ID和ID。 I know how to this using LinqToEF but I am at a loss how to this with Data Services or using OData query conventions for that matter. 我知道如何使用LinqToEF,但我不知道如何使用Data Services或使用OData查询约定。

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 any way to accomplish using Data Services / OData? 有没有办法使用Data Services / OData? I know I could probably hack it with a Service Operation but I would prefer not to do that. 我知道我可能会通过服务操作破解它,但我宁愿不这样做。

Cheers. 干杯。

Currently OData (the underlying protocol) doesn't support the Contains operation. 目前OData(底层协议)不支持Contains操作。 So that's why the client library does not translate the above query. 这就是客户端库不翻译上述查询的原因。 People are basically using two ways to overcome this limitation: 1) Use service operations as you noted. 人们基本上使用两种方法来克服这种限制:1)如你所指出的那样使用服务操作。 2) Construct a where clause dynamically which uses simple comparisons to compare the value to each item from the array. 2)动态构造一个where子句,它使用简单的比较来比较数组中每个项的值。 So if the array contains 1, 2, 3, the where would be data.ID == 1 || 因此,如果数组包含1,2,3,那么data.ID == 1 || data.ID == 2 || data.ID == 2 || data.ID == 3 The #2 solution is nice because it's a client side only change. data.ID == 3#2解决方案很好,因为它只是客户端改变。 The downside is, that it only works for small arrays. 缺点是,它只适用于小型阵列。 If the array contains too many items the expression gets too long and that leads to all kinds of troubles. 如果数组包含太多项,则表达式会变得太长,从而导致各种麻烦。 The #1 solution doesn't have the size problem, but you need to provide the operation on the server. #1解决方案没有大小问题,但您需要在服务器上提供操作。

Here is my realization of WhereIn() Method, to filter IQueryable collection by a set of selected entities: 这是我对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;
    }

And calling of this method looks like: 调用此方法看起来像:

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

Thank you men you really helped me :) :) 谢谢你们真的帮帮我:) :)

I did it like Vitek Karas said. 我这样做就像Vitek Karas说的那样。

1) Download the Dynamic query library Check this link 1)下载动态查询库检查此链接

No need to read it just download the Dynamic query library 无需阅读它只需下载动态查询库

2)Check the project named DynamicQuery. 2)检查名为DynamicQuery的项目。 In it you will find a class named Dynamic.cs . 在其中,您将找到一个名为Dynamic.cs的类。 Copy It to your project 将其复制到您的项目中

3)Generate your project( If you are using silverlight an error that say ReaderWriterLock is not found will appear. Don't be affraid. Just comment or delete the lines that make errors( there is just 6 or 7 lines that make errors) ) 3)生成你的项目(如果你正在使用silverlight,那么会出现一个错误,表示找不到ReaderWriterLock。不要害怕。只需评论或删除出错的行(只有6或7行会产生错误))

4) All done you just need now to write your query Example: ordersContext.CLIENTS.Where(" NUMCLI > 200 || NUMCLI < 20"); 4)所有完成你现在只需要编写查询示例: ordersContext.CLIENTS.Where(" NUMCLI > 200 || NUMCLI < 20");

All done. 全部做完。 If you have to use the 'Contains' method you just to write a method that iterate over your array and return the string that your request will use. 如果必须使用'Contains'方法,您只需编写一个迭代数组并返回请求将使用的字符串的方法。

    private string MyFilter()
{    string st = "";

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

        return st;
}

I hope you understand me and that i helped someone :) 我希望你理解我,我帮助了一个人:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM