Как сравнить даты в c# vs

У меня проект библиотека. Хочу вывести на экран задолжников (те кто по истечению 30 дней не вернули книгу). У меня есть столбцы book_issue_date и book_return_date.

Мой код

SqlConnection con = new SqlConnection();
con.ConnectionString = "data source = LAPTOP-2BMN08C6; database = library; integrated security = True";
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;

cmd.CommandText = "select * from IRBook where (book_issue_date.AddDays(30) > DateTime.Today and book_return_date is null)";
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];

Выдает ошибку:

Не удалось найти столбец "book_issue_date", определяемую пользователем функцию или агрегатную функцию "book_issue_date.AddDays". Также возможно, имя является неоднозначным."

Подскажите, пожалуйста, как правильно сделать запрос


Ответы (1 шт):

Автор решения: Alexander Petrov

AddDays() и DateTime.Today - это метод и свойство языка C#, а вы пытаетесь их выполнить в запросе SQL. Это невозможно.

Есть несколько способов сделать ваш запрос.
Один уже был указан в комментариях: использовать функцию DATEADD T-SQL.
А вместо DateTime.Today можно использовать функцию GETDATE() T-SQL.

var sql = "select * from IRBook where DATEADD(day, 30, book_issue_date) > GETDATE() and book_return_date is null";

using SqlConnection con = new SqlConnection(_connectionString);
using SqlCommand cmd = new SqlCommand(sql, con);
using SqlDataAdapter da = new SqlDataAdapter(cmd);

DataTable dt = new DataTable();
da.Fill(dt);
dataGridView1.DataSource = dt;

Обратите внимание на using - это автоматически очистит ресурсы, даже в случае возникновения исключения.
Также я использовал DataTable вместо DataSet, ведь вам нужна всего одна таблица, а не набор таблиц.

У этого способа есть недостаток, который состоит в том, что функция DATEADD будет применяться к каждой строке таблицы. Если строк много (миллионы), то это ухудшит производительность.
Можно, наоборот, вычесть дни из GETDATE(), занеся результат в переменную и подставить её в запрос. Оставляю это вам.


Другой способ: высчитаем нужную дату на клиенте и подставим её в запрос в виде параметра.

var sql = "select * from IRBook where book_issue_date > @date and book_return_date is null";

using SqlConnection con = new SqlConnection(_connectionString);

using SqlCommand cmd = new SqlCommand(sql, con);
cmd.Parameters.Add("date", SqlDbType.DateTime2).Value = DateTime.Today.AddDays(-30);

using SqlDataAdapter da = new SqlDataAdapter(cmd);

DataTable dt = new DataTable();
da.Fill(dt);
dataGridView1.DataSource = dt;

В параметре используйте точный тип SqlDbType. Я не знаю, какой именно тип у вас задан в БД.

→ Ссылка