Как зайти в Даркнет?!
25th January, 01:11
5
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
893
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
912
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Условные Запросы Linq
Мы работаем над средством просмотра журналов. Использование будет иметь возможность фильтровать по пользователю, серьезности и т.д. В Sql дней я бы добавил к строке запроса, но я хочу сделать это с Linq. Как я могу условно добавить, где предложения?
если вы хотите отфильтровать только определенные критерии, выполните что-то вроде этого
var logs = from log in context.Logs
select log;
if (filterBySeverity)
logs = logs.Where(p => p.Severity == severity);
if (filterByUser)
logs = logs.Where(p => p.User == user);
Это позволит вашему дереву выражений быть именно тем, что вы хотите. Таким образом, созданный SQL будет именно тем, что вам нужно, и не меньше.
Если вам нужно отфильтровать базу по списку / массиву, используйте следующее:
public List<Data> GetData(List<string> Numbers, List<string> Letters)
{
if (Numbers == null)
Numbers = new List<string>();
if (Letters == null)
Letters = new List<string>();
var q = from d in database.table
where (Numbers.Count == 0 || Numbers.Contains(d.Number))
where (Letters.Count == 0 || Letters.Contains(d.Letter))
select new Data
{
Number = d.Number,
Letter = d.Letter,
};
return q.ToList();
}
Я закончил использовать ответ, похожий на ответ Дарена, но с интерфейсом IQueryable:
IQueryable<Log> matches = m_Locator.Logs;
// Users filter
if (usersFilter)
matches = matches.Where(l => l.UserName == comboBoxUsers.Text);
// Severity filter
if (severityFilter)
matches = matches.Where(l => l.Severity == comboBoxSeverity.Text);
Logs = (from log in matches
orderby log.EventTime descending
select log).ToList();
Это создает запрос перед попаданием в базу данных. Команда не будет выполняться до тех пор, пока .ToList() в самом конце.
Когда дело доходит до условного linq, я очень люблю паттерн фильтров и труб.
http://blog.wekeroad.com/mvc-storefront/mvcstore-part-3/
В основном вы создаете метод расширения для каждого случая фильтра, который принимает IQueryable и параметр.
public static IQueryable<Type> HasID(this IQueryable<Type> query, long? id)
{
return id.HasValue ? query.Where(o => i.ID.Equals(id.Value)) : query;
}
Другой вариант - использовать что-то вроде PredicateBuilder, обсуждаемого здесь . Он позволяет вам писать код следующим образом:
var newKids = Product.ContainsInDescription ("BlackBerry", "iPhone");
var classics = Product.ContainsInDescription ("Nokia", "Ericsson")
.And (Product.IsSelling());
var query = from p in Data.Products.Where (newKids.Or (classics))
select p;
Обратите внимание, что я получил это только для работы с Linq 2 SQL. EntityFramework не реализует Expression.Invoke, что необходимо для работы этого метода. У меня есть вопрос по этому вопросу здесь .
Делающий это:
bool lastNameSearch = true/false; // depending if they want to search by last name,
имея это в заявлении where :
where (lastNameSearch && name.LastNameSearch == "smith")
это означает, что при создании окончательного запроса, если lastNameSearch -это false , запрос полностью опустит любой SQL для поиска по фамилии.
Я решил это с помощью метода расширения, чтобы позволить LINQ быть условно включенным в середине свободного выражения. Это устраняет необходимость разбивать выражение На операторы if .
.If() метод расширения:
public static IQueryable<TSource> If<TSource>(
this IQueryable<TSource> source,
bool condition,
Func<IQueryable<TSource>, IQueryable<TSource>> branch)
{
return condition ? source : branch(source);
}
Это позволяет вам сделать следующее:
return context.Logs
.If(filterBySeverity, q => q.Where(p => p.Severity == severity))
.If(filterByUser, q => q.Where(p => p.User == user))
.ToList();
Вот также версия IEnumerable<T> , которая будет обрабатывать большинство других выражений LINQ:
public static IEnumerable<TSource> If<TSource>(
this IEnumerable<TSource> source,
bool condition,
Func<IEnumerable<TSource>, IEnumerable<TSource>> branch)
{
return condition ? source : branch(source);
}
Недавно у меня было аналогичное требование, и в конце концов я нашел его в he MSDN. CSharp примеры для Visual Studio 2008
Классы, включенные в образец загрузки DynamicQuery, позволяют создавать динамические запросы во время выполнения в следующем формате:
var query =
db.Customers.
Where("City = @0 and Orders.Count >= @1", "London", 10).
OrderBy("CompanyName").
Select("new(CompanyName as Name, Phone)");
С его помощью можно динамически построить строку запроса во время выполнения и передать ее в метод Where():
string dynamicQueryString = "City = \"London\" and Order.Count >= 10";
var q = from c in db.Customers.Where(queryString, null)
orderby c.CompanyName
select c;
Это не самая красивая вещь, но вы можете использовать выражение lambda и передавать свои условия по желанию. В TSQL я делаю много следующего, чтобы сделать параметры необязательными:
Где Field = @FieldVar OR @FieldVar - это NULL
Вы можете повторить тот же стиль со следующим lambda (пример проверки подлинности):
MyDataContext дБ = новый MyDataContext();
пустота RunQuery(строка параметр1, параметр2 стринг, инт? param3){
Функция checkUser = пользователь =>
((param1.Length > 0)? user.Param1 = = param1 : 1 == 1) &&
((param2.Length > 0)? user.Param2 = = param2 : 1 == 1) &&
((param3 != null)? user.Param3 = = param3 : 1 == 1);
Пользователь foundUser = db.Users.SingleOrDefault(checkUser); }
Просто используйте оператор C#'s &&:
var items = dc.Users.Where(l => l.Date == DateTime.Today && l.Severity == "Critical")
Правка: Ну, надо читать внимательнее. Вы хотели знать, как условно добавить дополнительные предложения. В таком случае, я понятия не имею. :) Скорее всего, я просто подготовлю несколько запросов и выполню правильный, в зависимости от того, что мне понадобится.
Вы можете использовать внешний метод:
var results =
from rec in GetSomeRecs()
where ConditionalCheck(rec)
select rec;
...
bool ConditionalCheck( typeofRec input ) {
...
}
Это будет работать, но не может быть разбито на деревья выражений, что означает, что Linq-SQL будет выполнять код проверки для каждой записи.
Альтернативно:
var results =
from rec in GetSomeRecs()
where
(!filterBySeverity || rec.Severity == severity) &&
(!filterByUser|| rec.User == user)
select rec;
Это может работать в деревьях выражений, то есть будет оптимизировано значение от Linq до SQL.
Ну, я думал, что вы можете поместить условия фильтра в общий список предикатов:
var list = new List<string> { "me", "you", "meyou", "mow" };
var predicates = new List<Predicate<string>>();
predicates.Add(i => i.Contains("me"));
predicates.Add(i => i.EndsWith("w"));
var results = new List<string>();
foreach (var p in predicates)
results.AddRange(from i in list where p.Invoke(i) select i);
В результате получается список, содержащий "me", "meyou" и "mow".
Вы можете оптимизировать это, сделав foreach с предикатами в совершенно другой функции, которая ORs все предикаты.