В связи с тем, как был разработан веб-сайт, над которым я работаю, у меня есть проблема, которую я теперь должен решить.
Я постараюсь написать этот вопрос как независимый от языка, но сайт сделан в ASP.Netс C #.
Обзор
Структура нашего сайта выглядит следующим образом для любого данного "объекта":
- Страница ASPX
- Несколько пользовательских элементов управления (страницы ascx))
- Текстовые поля, комбинированные списки, метки, кнопки и т. Д.
Что это означает, если у нас есть страница пользователя иэта страница может иметь 3 пользовательских элемента управления.Один для информации о пользователе (имя, адрес электронной почты и т. Д.), Один для адреса (город, штат, почтовый индекс и т. Д.) И один для региональных настроек (часовой пояс, язык и т. Д.)
Все эти поляна 3 UserControls все хранятся в одной таблице в базе данных.
Теперь мы используем DataBinding и EntityFrameworks для заполнения данных, и это означает, что когда мы сохраняем объект, мы фактически вызываем save 3 раза (по 1 на UserControl).
(Language-Agnostic: на самом деле мы не присваиваем такие значения, как User.Name =
"Bob"
, это обрабатывается платформой)
Поскольку UserControl знает только о поляхон содержит, когда привязка данных сохраняет, «думает», что другие поля теперь пусты.(т.е. управление адресом сохраняется, и теперь «Email» и «Name» являются нулевыми значениями).Чтобы «исправить» это есть метод с именем «MapOldToNew», который выходит и захватывает старую запись и заполняет значения в объекте New, который собирается сохранить.Это универсальный, что означает, что у нас нет метода в Address Userttrol Address, который говорит: «иди, возьми поля имени и адреса электронной почты и заполни их», вместо этого он просматривает все свойства объекта (объекта) и, если значениеЗначение NULL
для объекта New, но NOT NULL
для объекта Old (тот, который в настоящее время находится в базе данных, который должен быть перезаписан), оно сделает значение New равным значению Old.
Проблема
Даты.Мы разрешаем пустые даты в нашей базе данных.
Если пользователь заполняет «День рождения» и сохраняет, у него теперь есть значение «День рождения» в поле в базе данных.
Если они возвращаются, очищают поле «День рождения» на веб-странице и сохраняют,метод MapOldToNew
захватывает старую запись, видит, что день рождения там не равен нулю и равен нулю для нового объекта, который должен быть сохранен, он переопределяет новое значение (NULL) на старое значение ('23.07.1981')например).
Решения?
- Переработать нашу систему, чтобы не использовать UserControls, а вместо этого иметь все элементы управления на одной странице, тем самым уменьшая количество раз, которое нам нужно сохранить, и не требуя
MapOldToNew
,А пока давайте предположим, что это невозможное решение (хотя я считаю, что это должно быть сделано по целому ряду причин). - Сохраните все даты в виде строк и выполните преобразование при загрузке и сохранении.(Строки не имеют такой же проблемы, потому что после изменения строки она становится пустой строкой, а не NULL)
- Не разрешать в базе данных даты NULL, всегда хранить
DateTime.MinValue
и непокажи его при загрузке.
Вот те идеи, которые я выдвинул из головы.Ради аргументов, давайте предположим, что № 1 невозможен (потому что у меня есть ощущение, что руководству не понравится время, которое потребуется для выполнения).
Как бы вы "исправили" это?
Другое объяснение
Здесь проблема разбита больше.Запись пользователя имеет 2 поля.Имя и дата рождения.
Предположим, что есть 1 ASPX-страница с двумя элементами UserControls (ascx).
UserControl1 имеет одну привязку DataPicker к «BirthDate».
UserControl2 имеет одну привязку TextBox к «Name».
Когда UserControl1 вызывает Update для ObjectContext, объект User, который он отправляет, выглядит следующим образом:
{ Name = NULL, BirthDate = 8/13/1980 }
MapOldToNew просматривает запись базы данных и видит, что Name должно быть "Bob", поэтому оно заполняет значение изапись сохраняется.
UserControl2 вызывает Update сейчас, и объект User выглядит следующим образом:
{ Name = "John", BirthDate = NULL }
MapOldToNew видит, что BirthDate имеет значение NULL, поэтому он перезаписывает его на 13.08.1980 из базы данных, а запись сохраняет и базу данныхимеет правильные значения.
Теперь предположим, что пользователь возвращается и удаляет значение BirthDate.Когда UserControl2 вызывает MapOldToNew, он видит, что BirthDate имеет значение NULL (что хочет пользователь), и перезаписывает его из базы данных.
Если он не перезаписывает его из базы данных, он всегда сохраняет его как NULL, и пользователь никогда не будетбыть в состоянии установить дату рождения.