Текстовый поиск по универсальному типу в Entity Framework - PullRequest
2 голосов
/ 27 января 2012

Я пытаюсь реализовать текстовый поиск для таблиц базы данных. У меня есть общий репозиторий, и я не хочу создавать производные для каждой модели, которую я мог бы представить, потому что в базе данных их довольно много.

Итак, код, с которым я сталкиваюсь, выглядит следующим образом:

var props = typeof(T).GetProperties()
    .Where(p => p.PropertyType == typeof(string));

IEnumerable<T> searched = null;
if (!string.IsNullOrWhiteSpace(searchTerm))
    searched = sorted.Where(c => props
        .Select(p => (string)p.GetValue(c, null))
        .Select(v => v.Contains(searchTerm))
        .Contains(true));

Я кормлю эту коллекцию PropertyInfo, полученную благодаря небольшому размышлению. Возможно, это не очень эффективная идея, но мне еще предстоит подумать о лучшем способе. Таким образом, это могут быть все свойства типа string (поиск по всем строкам в таблице) или выборочные свойства в модели, имеющие собственный атрибут Searchable.

Исключение времени выполнения, которое я получаю:

NotSupportedException : невозможно создать постоянное значение типа 'System.Reflection.PropertyInfo'. Только примитивные типы (такие как Int32, String и Guid ') поддерживаются в этом контексте.

Я вижу, что я использую отражение, но не совсем уверен, что именно вызывает здесь исключение. Если бы кто-то мог указать на это, это было бы очень ценно, но если бы кто-то мог предложить лучший способ сделать это, это было бы удивительно. Заранее спасибо!

1 Ответ

1 голос
/ 04 февраля 2012

Проблема в том, что при выполнении запроса LINQ он пытается создать запрос SQL для выполнения в базе данных. Сообщение об исключении указывает, что в запросе LINQ могут использоваться только примитивные типы, поскольку это единственные типы, которые могут быть успешно преобразованы в запрос SQL.

Надеемся, что для решения вашей проблемы вам просто нужно убедиться, что SQL-запрос к базе данных выполняется, прежде чем расширять запрос LINQ, используя непримитивные типы.

Я предполагаю, что переменная sorted в вашем фрагменте кода является запросом LINQ, поэтому вызовите sorted.AsEnumerable(), чтобы выполнить запрос SQL к базе данных, и тогда вы сможете выполнить функцию поиска.

searched = sorted.AsEnumerable()
                 .Where(c => props.Select(p => (string)p.GetValue(c, null))
                                  .Any(v => v.Contains(searchTerm)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...