Как я могу обеспечить, чтобы Linq to Sql не переопределял или не нарушал значения значений по умолчанию, отличные от NULL?
У меня есть база данных SQL Server с таблицей с этими полями:
- A
bit
со значением по умолчанию 1, NOT NULL
.
- A
smalldatetime
со значением по умолчанию gettime()
, NOT NULL
.
-
int
без значения по умолчанию IDENTITY
, NOT NULL
.
Когда я создаю Linq для SQL для этой таблицы, происходит следующее:
-
bit
не уделяется особого внимания.
-
smalldatetime
не предоставляется никакого специального лечения.
-
int
отмечен как IsDbGenerated
.
Это означает, что когда я делаю вставки с использованием Linq to SQL, произойдет следующее:
-
bit
будет отправлен как 0, переопределив значение по умолчанию. Right?
-
smalldatetime
будет отправлен как неинициализированный System.DateTime
, что приведет к ошибке на SQL-сервере, поскольку оно не падает с диапазоном smalldatetime SQL Server. Right?
-
IsDbGenerated
int
не будет отправлен; DB будет генерировать значение, которое Linq to SQL будет читать.
Какие изменения я должен внести, чтобы этот сценарий работал?
Подводя итог: я хочу непустые поля с присвоенными DB значениями по умолчанию, но я не хочу, чтобы они IsDbGenerated
, если это означает, что я не могу предоставлять значения для них при создании обновлений или вставок с использованием Linq to SQL. Я также не хочу их IsDbGenerated
, если это означает, что мне нужно вручную изменить код, сгенерированный Linq на SQL.
РЕДАКТИРОВАТЬ: Ответ кажется, что это ограничение в текущем Linq to SQL.
Ответы
Ответ 1
Сгенерированные классы Linq-To-Sql не выбирают константы значений по умолчанию.
Возможно, в будущем, но проблема в ограничениях - это не всегда простые значения, они также могут быть скалярными функциями, такими как GetDate()
, поэтому linq каким-то образом должен был бы знать, как их перевести. Короче говоря, он даже не пытается. Это также очень специфичный для конкретной базы данных тип.
- Вы можете написать генератор кода для создания частных классов объектов, где вы можете извлечь значение constriant по умолчанию.
- В качестве альтернативы код вашего бизнес-уровня может устанавливать значения по умолчанию в конструкторах из XML файла, и все, что вам нужно сделать, это сохранить обновленный xml файл.
- Вместо выполнения работы в конструкторах вы можете эмулировать sql и добавлять значения по умолчанию, проверяя ChangeSet перед отправкой изменений в базу данных.
Проблема, с которой вы сталкиваетесь, подробно описана в CodeProject - установка значений по умолчанию для привязанных к LINQ данных
Ответ 2
Я столкнулся с той же проблемой, bzlm, и пришел к такому же выводу. Просто нет хорошего способа получить поля с непустыми значениями с присвоенными DB значениями по умолчанию, работающими с Linq To Sql.
Работа, с которой я столкнулся, заключается в том, чтобы добавить метод SetDefaults(), очень похожий на тот, который Роберт Полсон связан с CodeProject и называет его в конструкторе по умолчанию моего базового класса сущности таблицы. Он работает хорошо для меня, потому что 95% времени я устанавливаю 0, пустую строку или getdate().
Ответ 3
Это означает, что когда я создаю вставки с использованием Linq для SQL, бывает:
- Бит будет отправлен как 0, переопределив значение по умолчанию. Правильно? - правильный
- smalldatetime будет отправлено как uninitialized System.DateTime, вызывая ошибку на SQL-сервере, поскольку он не падает с SQL Server диапазон smalldatetime. Правильно? - отправлено DateTime.MinValue
- IsDbGenerated int не будет отправлен; БД будет генерировать значение который Linq to SQL будет читать. - Если генерируется DB, тогда значение создается базой данных, если нет, то Linq ожидает, что пользователь установит значение.
Лучше всего установить их в конструкторе объекта или в закрытых полях, если вы не используете автоматические свойства.
Ответ 4
Вы можете создать другой файл для вашего datacontext (частичный класс), а затем использовать частичные методы InsertYOURENTITY и UpdateYOURENTITY для проверки ваших свойств и назначения правильных значений.
Вызовите ExecuteDynamicInsert или ExecuteDynamicUpdate после вашего кода и вы установите.