Я знаю, что об этом много, и я прочитал большинство из них. Однако для меня несколько вещей остаются неясными и до сих пор не работают.Свободное сопоставление NHibernate для DateTime со значением по умолчанию
Если у меня есть на моей схеме базы данных поле типа DateTime, и я хотел бы присвоить ему значение по умолчанию, я бы сделать что-то вроде этого:
create table [mySchema].[MyTable](
ObjectGuid uniqueidentifier CONSTRAINT Id PRIMARY KEY,
SomeTextToStore nvarchar(128) NULL,
CDate datetime NOT NULL DEFAULT GETDATE(),
CUser nvarchar(64) DEFAULT CURRENT_USER
);
GO
(Не знаю, если это важно: Я использую SQL Server Express 2014. Свободная конфигурация для SQL Server 2012.)
Это отлично работает при выполнении INSERT
с ISQL, вставляет временную метку момента добавления записи.
Использование свободно я хотел бы написать что-то вроде этого:
домена:
public class MyObject
{
public virtual Guid Id {get; set}
public virtual string SomeTextToStore {get; set;}
public virtual DateTime? CDate {get; set;}
public virtual string CUser {get; set;}
}
ПРИМЕЧАНИЕ: Я сделал CDate обнуляемым!
А класс отображения так:
class MyObjectMap : ClassMap<MyObject>
{
public MyObjectMap()
{
Table("MySchema.MyTable");
Id(x => x.Id).GeneratedBy.GuidComb();
Map(x => x.SomeTextToStore).Length(128).Nullable();
Map(x => x.CDate).Not.Nullable().Default("getdate()");
Map(x => x.CUser).Not.Nullable().Default("CURRENT_USER);
}
}
В программе (в моем случае это библиотека, которая может быть вызвана из нескольких типов программ) я сделать что-то вроде:
public void EnterSomeText()
{
using (var session = sessionManager.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var myObj = new MyObject();
myObj.SomeTextToStore("bla bla bla");
session.SaveOrUpdate(myObj);
transaction.Commit();
}
session.Close();
}
}
Это всегда заканчивается Исключение переполнения DateTime! (Переполнение SqlDateTime должно быть между 1/1/1753 12:00:00 и 12/31/9999 23:59:59 PM)
Похоже, что не передается значение CDate
вызывает проблему , Когда я добавляю по умолчанию в моей библиотеке, как например это работает:
...
myObj.SomeTextToStore("bla bla bla");
myObj.CDate = DateTime.Now; // <---- Set the date here
session.SaveOrUpdate(myObj);
...
Но это на самом деле не решение ....
Вопросы:
- Что же я делать неправильно/отсутствует?
- Какова правильная стратегия, когда определяет значения по умолчанию? Делать это в базе данных или просто в коде? (Когда начинают простой новый проект ванили, я предпочел бы делать все от C# код, даже создавать, а затем обновить схему ...)
- Что касается доменных классов: Разумно создать конструктор, , заполняющие поля с настройками по умолчанию?
Я делаю это для поля CUser
, потому что в CUser
Я хотел бы добавить текущий пользовательский контекст
public MyObject()
{
var o = System.Security.Principal.WindowsIdentity.GetCurrent();
if (o != null)
{
CUser = o.Name;
}
}
Вместо того, чтобы заполнить поле CDate с текущей датой в моей библиотеке слоя DB-доступа I Could сделайте это также в конструкторе домена-класса, такого как:
public MyObject()
{
var o = System.Security.Principal.WindowsIdentity.GetCurrent();
if (o != null)
{
CUser = o.Name;
}
CDate = DateTime.Now;
}
Большое спасибо за вашу помощь и комментарии!
Вы прочитали этот [пост] (/ a/35700837/1178314) о значениях по умолчанию? Определение значений по умолчанию при сопоставлении почти только для генерации dml (создание ограничения по умолчанию в db), а не для определения значений по умолчанию для ваших вновь созданных объектов. Это должно быть сделано через инициализаторы конструктора или полей, как и для любого класса. –
+1 @ Frédéric. Это уточняет вопрос о конструкторе. Для этого требуется написать частный метод Init() и вызвать его из конструктора, так как не нужно присваивать значения виртуальным реквизитам в конструкторе .... – ThommyB