Извините, если название вводит в заблуждение, не знал, как его описать.
Моя конечная цель - иметь метод расширения IQueryable<T>
и некоторую форму (см., Например, ниже) выражения, которая позволит мне вернуть IQueryable<EntityIndex<T>>
(или аналогичный), который содержит исходный T
в поле Entity
и массив / перечислимый элемент, содержащий элементы, описываемые формой выражения some .
Я знаю, что это не имеет смысла, надеюсь, это будет после примера ...
Это то, что я имею до сих пор:
class EntityIndex<T, TKey>
{
T Entity { get; set; }
// Doesn't have to be IEnumerable, whatever is easier
IEnuermable<TKey> Index { get; set; }
}
static class Elsewhere
{
[Extension()]
public IQueryable<EntityIndex<T, TKey>> IndexBy<T, TKey>(this IQueryable<T> source, Expression<Func<T, TKey[]>> indexSelector)
{
return source.Select(n => new EntityIndex<T, TKey> {
Entity = n,
Index = new T[] { n }.Select(indexSelector)
});
}
}
Примечание: вышеприведенный не компилирует , он просто там, чтобы попытаться показать, чего я пытаюсь достичь.
Я использовал стандартный селектор , но неоптимально должен был произвольно создать массив T
в присваивании свойству 'Index', чтобы иметь возможность применить селектор. Я надеюсь, что лучший выбор параметра может решить эту проблему, но, возможно, нет. Основная проблема в том, что это не компилируется, поэтому, если есть небольшой твик, который позволит мне работать, это нормально, если вы можете понять мой бред и понять, что я пытаюсь сделать, и случайно узнать лучший способ Я бы очень признателен.
В идеале мне нужно, чтобы решение было понятно движку L2S, но я не уверен, что вышеизложенное - благодаря введению класса EntityIndex
, но я надеюсь, что оно сработает. как анонимный класс.
EDIT:
Хороший вопрос, Дэмиен, большую картину, вероятно, гораздо проще описать ...
Я хочу метод расширения, который принимает выражение, выражение должно описывать, какие поля в сущности для index , которые будут использоваться после этого конкретного выражения, чтобы можно было применить критерий (условие where) в выбранные поля.
Короче говоря, во многих местах кода мы используем поиск по шаблону. Если у меня есть EntityA с Property1, Property2, Property3 и т. Д., Я нередко вижу такой код:
Рукописно, прошу прощения за незначительные опечатки
public string[] WildcardSearch(string prefixText, int count)
{
string searchTerm = prefixText.Replace(wildcard, string.Empty);
if (prefixText.StartsWith(wildcard) && prefixText.EndsWith(wildcard)) {
return entitySet.Where(n => n.Property1.Contains(searchTerm) || n.Property2.Contains(searchTerm)).Select(n => n.Property3).ToArray();
} else if (prefixText.StartsWith(wildcard)) {
return entitySet.Where(n => n.Property1.EndsWith(searchTerm) || n.Property2.EndsWith(searchTerm)).Select(n => n.Property3).ToArray();
// you get the picture, same with EndsWith, no wildcards defaults to contains...
}
}
EDIT:
Дальнейшее пояснение - используя приведенный выше WildcardEarch в качестве примера, я надеялся, что у меня будет возможность выбрать селектор следующим образом или аналогично:
Func<EntityA, IEnumerable<string>> indexSelector = n => new string[] {
n.Property1,
n.Property2
};
// Alternatively, a ParamArray of keySelector might work?
Func<EntityA, string>[] keySelectors = new Func<EntityA, string>[] {
n => n.Property1,
n => n.Property2
};
Учитывая адекватное выражение, описывающее, какие поля в сущности для поиска, возвращая IQueryable<EntitySearch<T>>
, как показано выше, я надеялся, что смогу применить один критерий, похожий на:
Func<EntitySearch<T>, bool> criterion = n => false;
if (wildcardIsContains) {
criterion = n => n.Values.Any(x => x.Contains(searchTerm));
} else if (wildCardIsStartsWith) {
criterion = n => n.Values.Any(x => x.Contains(searchTerm));
//etc
}
Учитывая расширение в самом верху, которое я не могу заставить работать, и эту логику критерия, я должен быть в состоянии взять IQueryable<T>
, выбрать несколько полей и применить соответствующий поиск по шаблону для полей, наконец, возвращая IQueryable<T>
снова добавив фильтрацию.
Thanks¬!
Пожалуйста, прокомментируйте, если вам нужно больше информации / разъяснений ...
EDIT:
Честная @subkamren и спасибо за интерес. Некоторые неуниверсальные примеры могут быть полезны. Я напишу что-нибудь и скоро добавлю. Пока что некоторые пояснения основаны на вашем комментарии ...
Учитывая IQueryable<Animal>
, я хочу расширение, позволяющее мне выбирать поля в Animal, по которым я собираюсь искать / индексировать. Например, Animal.Description, Animal.Species.Name
и т. Д. Это расширение должно возвращать что-то вроде IIndexedQueryable<Animal>
. Это проблема, которую я пытаюсь решить в вопросе выше. Упомянутая более широкая картина, с которой я был бы чрезвычайно рад, если вы готовы помочь, выглядит следующим образом:
Интерфейс IIndexedQueryable<T>
В свою очередь, я бы хотел расширение, для которого может потребоваться string
поисковый запрос. Расширение должно разрешать символы подстановки в поисковом запросе, расширять исходный IQueryable с необходимым критерием для поиска по индексированным полям и возвращать IQueryable<T>
снова.
Я ценю, что это можно сделать за один шаг, но я надеялся сделать это таким образом, чтобы позже я мог рассмотреть добавление третьего метода расширения, применимого к IIndexedQueryable<T>
, позволяющего мне выполнять поиск в свободном тексте с SQL Server... ^^ Есть смысл?
Это, по крайней мере, более широкая картина, этот вопрос касается, прежде всего, возможности указать поля, которые я намерен индексировать, таким образом, чтобы я мог использовать их после этого, как упомянуто здесь.