Пользовательский метод расширения Linq для списка выбора jqGrid - PullRequest
0 голосов
/ 28 марта 2011

У меня есть собственный метод для получения строки, который используется с jqGrid для списков выбора для поиска.

Требуемый формат строки: ":All;value1:text1;value2:text2" В настоящее время у меня есть следующий метод для достижения этой цели путем повторного использования:

public static string jqGridFilterSelectList<TSource>(this IQueryable<TSource> source,Expression<Func<TSource, string>> selector)
{
     return string.Join(";", source.Select(selector).Distinct().ToArray()); 
}

Это работает нормально, но требует, чтобы вызов был таким:

string filterSelectList = service.GetAllUsers().jqGridFilterSelectList(x=>x.User + ":" + x.User);

Я не очень доволен тем, что мне нужно использовать селектор, такой как x=>x.User + ":" + x.User.Я хотел бы преобразовать это в 2 перегрузки, подобные этой (псевдокод !!)

// case where we want the value and text of the select list to be the same
public static string jqGridFilterSelectList<TSource>(this IQueryable<TSource> source,Expression<Func<TSource, string>> selector)
{
     return string.Join(";", source.Select(selector + ":" + selector).Distinct().ToArray()); 
     //obviously this won't work, but is it possible in some other way while executing it on the database still? Also is it possible to insist the selector only contains 1 column.
}

//case where we want different text and value
public static string jqGridFilterSelectList<TSource>(this IQueryable<TSource> source,Expression<Func<TSource, string>> textSelector,Expression<Func<TSource, string>> valueSelector)
{
     return string.Join(";", source.Select(valueSelector + ":" + textSelector).Distinct().ToArray()); 
}

Полагаю, я мог бы добиться этого, используя динамический linq, но мне интересно знать, возможно ли это.

Ответы [ 2 ]

1 голос
/ 28 марта 2011

Еще один способ реализовать то, что вам нужно, это использовать dataUrl и buildSelect параметры поиска .

В случае строки value в форме ": Все; значение1: текст1; значение2: текст2 "не будет построено, пока оно действительно не понадобится (до первого поиска).Когда пользователь нажимает на диалоговое окно поиска, jqGrid получает данные из dataUrl.Метод сервера может иметь очень понятный интерфейс и возвращать JSON-представление List<string>.На стороне клиента вы определяете дескриптор события buildSelect, который преобразует ["text1", "text2", ...] в <select>.Это все.Пример использования этих способов вы можете найти здесь .По сравнению с примером вам нужно только добавить дополнительную опцию <option value="">All</option> в элементе выбора.

Иногда вам необходимо дополнительно использовать ajaxSelectOptions jqGrid для настройки соответствующего запроса $.ajax, который получаетданные для списка выбора.

Преимущества способа:

  1. Серверный метод, предоставляющий данные для списка выбора, может иметь очень понятный интерфейс и возвращать только List.
  2. Размер данных, отправляемых с сервера, будет уменьшен, потому что вы не отправляете «value1» и «text1» дважды, потому что значения совпадают с текстом в вашем случае.
  3. Вы можетеиспользуйте тот же метод для editoptions , в случае вашей сетки используйте любой метод редактирования (inline, редактирование формы или ячейки).В другой реализации buildSelect вы должны только пропустить вставку <option value="">All</option> в список выбора.
  4. Данные для элемента select будут собраны, только если они действительно необходимы: при первом использовании поиска.
  5. Ответ HTTP GET от сервера для списка выбора может кэшироваться автоматически, и если вам нужны те же данные выбора в другой сетке, предыдущий ответ сервера можно получить непосредственно из кэша локального браузера.
1 голос
/ 28 марта 2011

Если я правильно понимаю, вы почти написали это:

public static string jqGridFilterSelectList<TSource>(
    this IQueryable<TSource> source, 
    Expression<Func<TSource, string>> selector
)
{
     var compiled = selector.Compile();
     return string.Join(";", 
         source.Select(x => compiled(x) + ":" + compiled(x))
             .Distinct().ToArray()
     ); 
}

//case where we want different text and value
public static string jqGridFilterSelectList<TSource>(
    this IQueryable<TSource> source, 
    Expression<Func<TSource, string>> textSelector, 
    Expression<Func<TSource, string>> valueSelector
)
{
     return string.Join(";", 
         source.Select(x => valueSelector.Compile()(x) + ":" + textSelector.Compile()(x))
             .Distinct().ToArray()
     ); 
}

Вам просто нужно вызвать ваши функции выбора для получения значений.Дайте мне знать, если я неправильно понимаю ваш вопрос.

По второму вопросу: можно ли настаивать на том, что селектор содержит только 1 столбец, простой ответ - нет - селектор может быть практически любымдопустимый Func, который принимает TSource и возвращает string, и нет никакого способа ограничить то, что может быть сделано внутри (если вы не хотите исследовать предоставленное дерево выражений , но это будет более сложным, чемрезультат, конечно).

РЕДАКТИРОВАТЬ : ОК, так что это какой-то поставщик SQL LINQ, Entity Framework?Итак, давайте попробуем немного по-другому.Я не знаю, сработает ли это, но давайте сначала попробуем извлечь данные и объединить объекты:

public static string jqGridFilterSelectList<TSource>(
    this IQueryable<TSource> source, 
    Expression<Func<TSource, string>> selector
)
{
     var compiled = selector.Compile();
     return string.Join(";", 
         source.Distinct().AsEnumerable()
             .Select(x => compiled(x) + ":" + compiled(x))
             .ToArray()
     ); 
}

//case where we want different text and value
public static string jqGridFilterSelectList<TSource>(
    this IQueryable<TSource> source, 
    Expression<Func<TSource, string>> textSelector, 
    Expression<Func<TSource, string>> valueSelector
)
{
     return string.Join(";", 
         source.Distinct().AsEnumerable()
             .Select(x => valueSelector.Compile()(x) + ":" + textSelector.Compile()(x))
             .ToArray()
     ); 
}

Дополнительный вызов ToEnumerable переключает между базами данных и-процессная обработка.Предполагая, что ваши селекторы детерминированы и не имеют побочных эффектов, вы можете работать с уже выбранными TSource элементами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...