Динамический LINQ с ICollection.Any () [duplicate]

Это обсуждается в учебнике Oracle Определение и запуск потока :

Какую из этих идиом вы должны использовать? Первая идиома, которая использует объект Runnable, является более общей, поскольку объект Runnable может подклассифицировать класс, отличный от Thread. Вторая идиома проста в использовании в простых приложениях, но ограничена тем, что ваш класс задачи должен быть потомком Thread. В этом уроке основное внимание уделяется первому подходу, который отделяет задачу Runnable от объекта Thread, выполняющего задачу. Этот подход не только более гибкий, но применим к API-интерфейсам управления потоками высокого уровня, рассмотренным позже.

Другими словами, реализация Runnable будет работать в сценариях, где ваш класс расширяется класс, отличный от Thread. Java не поддерживает множественное наследование. Кроме того, расширение Thread не будет возможно при использовании некоторых высокоуровневых API управления потоками. Единственный сценарий, когда расширение Thread предпочтительнее, - это небольшое приложение, которое в будущем не будет обновляться. Практически лучше реализовать Runnable, поскольку он более гибкий по мере роста вашего проекта. Изменение дизайна не окажет большого влияния, поскольку вы можете реализовать множество интерфейсов в java, но только расширить один класс.

2
задан marc_s 11 August 2016 в 08:00
поделиться

5 ответов

Это возможно, как только вы будете следовать правилам Expression Language .

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

query = db.Customers.Where("Categories.Any(Code == \"Retail\")");
3
ответ дан Ivan Stoev 20 August 2018 в 10:59
поделиться

Метод расширения linq был принят аргументом типа System.Func<TSource, Int32, Boolean>

  • . В вашем случае a Func, который получает Customer в качестве аргумента и возвращает true / false. Результатом функции Where будет все Customers, что Func возвращен true для.

"Categories.Any(Code == 'Retail')" является строкой, а не Func, поэтому не может передается как аргумент методу Where.

Возможно, что вы ищете, если вы хотите сохранить гибкий запрос, это что-то вроде:

Public Customer[] QueryCustomers(Func<Customer,bool> predicate)
{
    var result =  db.Customers.Where(c=> predicate(c)).ToArray();
    return result;
}

Использование :

var retailCustomers =
      QueryCustomers(customer => customer.Categories.Any(Code == 'Retail'))   

Или любой другой запрос, который вы могли бы составить во время выполнения / компиляции:

var customersWithNoCategories =
      QueryCustomers(customer => customer.Categories.Count == 0)
1
ответ дан Avi Turner 20 August 2018 в 10:59
поделиться

Разве это не должно быть ниже?

refinedCustomerList = db.Customers.Where(customer => customer.Categories.Any(Code == 'Retail'));

В приведенном выше списке будут все клиенты, категория которых «Розничная торговля»

1
ответ дан nick-s 20 August 2018 в 10:59
поделиться

Вам нужно что-то вроде этого:

query =  db.Customers.Where(x => x.Categories.Where(y => y.Code == "Retail").Any());
1
ответ дан Sherlock 20 August 2018 в 10:59
поделиться
  • 1
    Мне нужно, чтобы предложение было строкой. – Daler 10 June 2016 в 05:26
  • 2
    @ Далер по какой причине? – Sherlock 10 June 2016 в 05:26
  • 3
    Поскольку это не предопределено, предложение будет генерироваться во время выполнения. – Daler 10 June 2016 в 05:28
  • 4
    Почему он генерируется во время выполнения? если есть варианты, почему бы просто не запускать разные запросы в зависимости от параметров – Toxicable 10 June 2016 в 05:31
  • 5
    @Daler Я сомневаюсь, что это было бы возможно, насколько я знаю, вы можете передавать строки только для выражений, но для функций API как часть строки я никогда не сталкивался с такими случаями – Sherlock 10 June 2016 в 05:33

Вы можете создать свою собственную среду выполнения Expression:

Expression<Func<Customer, bool>> myRuntimeExpression = null;

if(condition1)
{
    myRuntimeExpression = cust => cust.Categories.Any(cat => cat.Code == "Retial"); // or some local variable
}
else if(condition2)
{
    myRuntimeExpression = cust => cust.Categories.Any(cat => cat.Id = someId) == false;
}
else if(condition3)
{

}

var query = DB.Customers.Where(myRuntimeExpression);

Однако, если вам нужно построить более сложные запросы, посмотрите Динамические запросы в Linq с помощью выражений .

2
ответ дан user3185569 20 August 2018 в 10:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: