#c# #entity-framework #linq
#c# #entity-framework #linq
Вопрос:
У меня есть ввод и таблица данных, когда пользователь вводит этот ввод, я фильтрую данные при вводе ключа в зависимости от того, что ввел пользователь. точно так же, как таблицы данных.net, но это с нуля для обучения.
Таблица данных содержит 3 столбца: полное имя (строка), город (строка) и дата рождения (дата-время).
Я хочу, чтобы, если пользователь введет, например: «2 /», это даст ему все DOB, в которых есть 2 /. пока это мой код (я перепробовал много, но ни один не сработал).
var data = _context.Person.Where(p => p.DateOfBirth.Value
.ToString("d").Split()[0].Contains(SearchQuery)).ToList();
// Split(), чтобы удалить временную часть.
И:
var data = _context.Person.Where(p => p.DateOfBirth.Value
.ToString().Contains(SearchQuery)).ToList();
Но оба дают мне исключение: «Перевод системы методов.Дата-время.Ошибка toString’
Комментарии:
1. Можете ли вы показать нам определение
Person
?2. Если
DateOfBirth
используется datetime.Day
3. класс Person { общедоступный длинный идентификатор { get; set; } общедоступная строка Fullname { get; set; } общедоступная дата-время? DateOfBirth { получить; установить; } }
4. Ооо.. Я сомневаюсь, что это сработает хорошо. Я думаю, вам следует уточнить свои требования, а не пытаться закодировать это.. Если пользователь вводит
2/
, и вы хотите вернуть даты рождения, такие как 2002/11/31, 2010/12/31, 2000/2/11, и вы хотите делать это при каждом нажатии клавиши … Тьфу5. @Charlieface но что, если пользователь продолжит вводить «2/02 /», потому что я как бы показываю данные, пока пользователь печатает.
Ответ №1:
Когда вы используете LINQ-to-entities, ваш код на C # фактически не выполняется. Он анализируется. Среда выполнения проанализирует код C # как выражение и преобразует каждый символ в некоторую часть строки SQL. Затем он отправляет эту строку в базу данных для выполнения на сервере. Сервер не поддерживает те же виды форматирования даты, поэтому выражение вызова вашего метода не поддерживается; нет способа перевести его в строку SQL.
Однако большая проблема здесь заключается в том, что вы не должны обращаться к базе данных при каждом нажатии клавиши; это вызовет проблемы.
Вместо этого обратитесь к базе данных только один раз, при загрузке формы. Кэшируйте список в памяти. Вы можете сделать это, вызвав ToList
. Сохраните результаты в переменной-члене.
List<Person> _data;
void Form_Load(object sender, EventArgs e)
{
_data = _context.Person.ToList();
}
Теперь, когда у вас есть локальная копия, вы можете использовать ее вместо вызова базы данных. И поскольку ваш запрос LINQ не обязательно переводить в инструкцию SQL, вы можете использовать любой метод c #, который вы хотите.
void SearchQuery_KeyUp(object sender, KeyEventArgs e)
{
var data = _data.Where(p => p.DateOfBirth.Value
.ToString("d").Split()[0].Contains(SearchQuery)).ToList();
Display(data);
}
Ответ №2:
Вы можете использовать LIKE
оператор, который приблизится к достижению того, чего вы хотите.
var data = _context.Person.Where(p => EF.Functions.Like(p.DateOfBirth, $"%{searchquery}%")).ToList();
Проблема будет заключаться в том, что если вы сохраняете даты в виде DateTime
DateTime2
DateTimeOffset
поля или, то их представление в базе данных будет отличаться от введенного вами строкового представления. т. Е. В них, вероятно, не будет ‘/’ (хотя это невозможно сказать, поскольку вы не упоминаете свою базу данныхтехнология).
Ответ №3:
Если вы сначала загружаете таблицу в память, вызывая, например context.person.ToList()
, ваш метод должен работать и не должен завершаться преобразованием DateTime
в a string
.
Я бы предложил следующее:
_context.Person.ToList().Where(p => p.DateOfBirth.Value
.ToString("dd/MM/yyyy").Contains(SearchQuery)).ToList();