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

时间:2010-08-19 11:38:41

标签: 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);

有没有办法使用Data Services / OData?我知道我可能会通过服务操作破解它,但我宁愿不这样做。

干杯。

3 个答案:

答案 0 :(得分:8)

目前OData(底层协议)不支持Contains操作。这就是客户端库不翻译上述查询的原因。 人们基本上使用两种方法来克服这种限制: 1)按照您的说明使用服务操作。 2)动态构造一个where子句,它使用简单的比较来比较数组中每个项的值。因此,如果数组包含1,2,3,那么data.ID == 1 || data.ID == 2 || data.ID == 3 #2解决方案很好,因为它只是客户端的变化。缺点是,它只适用于小型阵列。如果数组包含太多项,则表达式会变得太长,从而导致各种麻烦。 #1解决方案没有大小问题,但您需要在服务器上提供操作。

答案 1 :(得分:4)

这是我对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;
    }

调用此方法看起来像:

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

答案 2 :(得分:0)

谢谢你们,你们真的帮了我:) :)

我做的就像Vitek Karas说的那样。

1)下载动态查询库 请检查此link

无需阅读它只需下载动态查询库

2)检查名为DynamicQuery的项目。在其中,您将找到一个名为Dynamic.cs的类。将其复制到您的项目

3)生成您的项目(如果您正在使用silverlight,则会出现错误,表示未找到ReaderWriterLock。请不要害怕。只需评论或删除出错的行(只有6或7行可以错误))

4)完成所有操作后,您只需编写查询即可 示例:ordersContext.CLIENTS.Where(" NUMCLI > 200 || NUMCLI < 20");

全部完成。如果必须使用'Contains'方法,您只需编写一个迭代数组并返回请求将使用的字符串的方法。

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

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

        return st;
}

我希望你理解我,并且我帮助了某人:)