Выберите объекты, где ID в массиве int - Службы данных WCF, LINQ - PullRequest
6 голосов
/ 19 августа 2010

Я хотел бы вернуть набор сущностей с идентификатором, который содержится в списке или массиве идентификаторов, с использованием LINQ и Data Services.Я знаю, как это сделать с помощью 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 ]

8 голосов
/ 20 августа 2010

В настоящее время OData (базовый протокол) не поддерживает операцию Contains. Вот почему клиентская библиотека не переводит вышеуказанный запрос. Люди в основном используют два способа преодолеть это ограничение: 1) Используйте сервисные операции, как вы отметили. 2) Создайте предложение where динамически, которое использует простые сравнения для сравнения значения каждого элемента из массива. Так что, если массив содержит 1, 2, 3, где будет data.ID == 1 || data.ID == 2 || data.ID == 3 Решение №2 приятно, потому что это изменение только на стороне клиента. Недостатком является то, что он работает только для небольших массивов. Если массив содержит слишком много элементов, выражение становится слишком длинным, что приводит к всевозможным проблемам. Решение № 1 не имеет проблемы с размером, но вам нужно предоставить операцию на сервере.

4 голосов
/ 12 августа 2014

Вот моя реализация метода 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);
0 голосов
/ 19 сентября 2012

Спасибо, мужчины, вы действительно помогли мне :):)

Я сделал это, как сказал Витек Карас.

1) Скачать библиотеку динамических запросов Проверьте эту ссылку

Не нужно читать, просто скачайте библиотеку динамических запросов

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

Надеюсь, ты меня понимаешь и что я кому-то помог:)

...