Incercept, когда DateTime.Now используется при записи в базу данных - PullRequest
3 голосов
/ 03 июня 2011

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

Я ищу способ узнать, когда разработчик использует DateTime.Now при записи в базу данных.

Мы используем Sql Server 2008 с EF4 или nHibernate 3.0.

Можно ли перехватить значение даты и времени, когда оно содержит информацию о часовом поясе на низкоуровневом уровне, например, в Sql Server или в NH / EF?

Ответы [ 6 ]

3 голосов
/ 05 июня 2011

Вы можете добавить следующий прослушиватель событий:

public class DateTimeEventListener : IPreUpdateEventListener,
                                     IPreInsertEventListener
{
    public bool OnPreUpdate(PreUpdateEvent e)
    {
        foreach (var value in e.State)
            if (value is DateTime && ((DateTime)value).Kind != DateTimeKind.Utc)
                throw new Exception("Non-UTC DateTime used");
    }

    public bool OnPreInsert(PreInsertEvent e)
    { /*Same as OnPreUpdate*/ }
}

(это полностью не проверено и может завершиться ошибкой со значениями, извлеченными из БД. Использовать в качестве начальной точки)

0 голосов
/ 05 июня 2011

Вы не должны вводить код для обеспечения соблюдения правил в стиле кодирования ваших разработчиков. Вы без необходимости вносите накладные расходы в свое приложение. Есть способы, которыми вы можете решить эту проблему:

a) Регулярно проверяйте код и убедитесь, что весь проверенный код проверен

б) Другой способ - применить это в вашей модели данных. Почему бы вам не использовать свойство DateTimeOffset в этом поле и перестать беспокоиться.

0 голосов
/ 03 июня 2011

Если оставить в стороне аргумент о том, должны ли даты храниться в UTC или нет, место для проверки такого рода вещей в вашем коде находится в процессе сборки или при сбое, используя ловушку перед фиксацией.

Последнее позволит разработчику только зафиксировать код, соответствующий вашим стандартам.Делать это на уровне базы данных слишком поздно, ИМО.

0 голосов
/ 03 июня 2011

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

Вероятно, невозможно обнаружить использование DateTime.Now в запросах SQL во время выполнения.Вам лучше пройтись по своему коду и исключить все случаи использования DateTime.Now.Везде.Установите стандарт кодирования так, чтобы все даты и время в вашей программе были представлены в формате UTC, кроме случаев, когда они должны быть выведены по местному времени или в некотором другом часовом поясе.Это будет намного лучшим долгосрочным решением проблемы.

0 голосов
/ 03 июня 2011

Я думаю, что в NHibernate вы можете использовать класс перехватчика для переопределения базовых методов, таких как OnLoad, в OnSave.Вы можете попытаться перехватить тип свойства и управлять там вашей датой перед вставкой в ​​db.

посмотрите здесь:

http://knol.google.com/k/fabio-maulo/nhibernate-chapter-11-interceptors-and/1nr4enxv3dpeq/14#

0 голосов
/ 03 июня 2011

Вы можете написать триггер в своей базе данных, который регистрирует (или делает что-то еще), когда DateTime, который, как вы ожидаете, будет находиться сейчас, сейчас не близок к UTC.

Вы можете задать для полей даты по умолчанию для слоя EF или NHibernate значение UTC. Теперь разработчикам не нужно их устанавливать.

Вероятно, лучше, вы можете просто найти код DateTime.Now и просмотреть использование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...