Это обсуждается в учебнике Oracle Определение и запуск потока :
Какую из этих идиом вы должны использовать? Первая идиома, которая использует объект Runnable, является более общей, поскольку объект Runnable может подклассифицировать класс, отличный от Thread. Вторая идиома проста в использовании в простых приложениях, но ограничена тем, что ваш класс задачи должен быть потомком Thread. В этом уроке основное внимание уделяется первому подходу, который отделяет задачу Runnable от объекта Thread, выполняющего задачу. Этот подход не только более гибкий, но применим к API-интерфейсам управления потоками высокого уровня, рассмотренным позже.
Другими словами, реализация
Runnable
будет работать в сценариях, где ваш класс расширяется класс, отличный отThread
. Java не поддерживает множественное наследование. Кроме того, расширениеThread
не будет возможно при использовании некоторых высокоуровневых API управления потоками. Единственный сценарий, когда расширениеThread
предпочтительнее, - это небольшое приложение, которое в будущем не будет обновляться. Практически лучше реализоватьRunnable
, поскольку он более гибкий по мере роста вашего проекта. Изменение дизайна не окажет большого влияния, поскольку вы можете реализовать множество интерфейсов в java, но только расширить один класс.
Это возможно, как только вы будете следовать правилам Expression Language .
Например, строковые литералы должны быть заключены в двойные кавычки:
query = db.Customers.Where("Categories.Any(Code == \"Retail\")");
Метод расширения linq был принят аргументом типа System.Func<TSource, Int32, Boolean>
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)
Разве это не должно быть ниже?
refinedCustomerList = db.Customers.Where(customer => customer.Categories.Any(Code == 'Retail'));
В приведенном выше списке будут все клиенты, категория которых «Розничная торговля»
Вам нужно что-то вроде этого:
query = db.Customers.Where(x => x.Categories.Where(y => y.Code == "Retail").Any());
Вы можете создать свою собственную среду выполнения 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 с помощью выражений .