C# 具有默认值的DateTime的Fluent NHibernate映射
我知道关于这一点有很多线索,我读过其中的大部分。然而,对我来说,有两件事仍然不清楚,仍然不起作用 如果我的数据库架构上有一个DateTime类型的字段,并且我想给它指定一个默认值,我会这样做:C# 具有默认值的DateTime的Fluent NHibernate映射,c#,sql-server,nhibernate,fluent-nhibernate,fluent-nhibernate-mapping,C#,Sql Server,Nhibernate,Fluent Nhibernate,Fluent Nhibernate Mapping,我知道关于这一点有很多线索,我读过其中的大部分。然而,对我来说,有两件事仍然不清楚,仍然不起作用 如果我的数据库架构上有一个DateTime类型的字段,并且我想给它指定一个默认值,我会这样做: create table [mySchema].[MyTable]( ObjectGuid uniqueidentifier CONSTRAINT Id PRIMARY KEY, SomeTextToStore nvarchar(128) NULL, CDate 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
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);
}
}
(不知道这是否重要:我正在使用SQL Server Express 2014。Fluent配置适用于SQL Server 2012。)
当从ISQL执行INSERT
时,这可以很好地工作,插入记录添加时的时间戳
使用fluent,我会写以下内容:
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
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 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为空
还有这样一个映射类:
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
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);
}
}
这总是以日期时间溢出异常结束!(SqlDateTime溢出。必须介于1/1/1753 12:00:00 AM和12/31/9999 11:59:59 PM之间)
问题似乎是由于未向文件CDate
传递值造成的。当我在我的库中添加默认值时,它会起作用:
...
myObj.SomeTextToStore("bla bla bla");
myObj.CDate = DateTime.Now; // <---- Set the date here
session.SaveOrUpdate(myObj);
...
不必在我的DB访问层库中用当前日期填充CDate字段,我也可以在域类的构造函数中这样做:
public MyObject()
{
var o = System.Security.Principal.WindowsIdentity.GetCurrent();
if (o != null)
{
CUser = o.Name;
}
CDate = DateTime.Now;
}
非常感谢您的帮助和评论 您已在数据库中将此列定义为
notnull
,并在映射中将其定义为Nullable()
。FluentNHibernate正在向数据库发送DbNull
,该数据库将被拒绝,因为数据库列不可为null
你应该决定你的逻辑在哪里。这是你的代码还是数据库谁是主人
例如,在中讨论了在FlientNHibernate中设置默认值
建议代码如下:
Map(x => x.SubmitionDate).Default("getdate()").Not.Nullable();
一般来说,我总是建议使用(付费工具)查看哪些查询进入数据库,以及它们失败的原因。对于优化来说非常宝贵,您正在使用ORM,现在要小心 对于这种类型的映射,我通常在映射中执行以下操作:
DynamicInsert();
DynamicUpdate();
这样,如果在C#中有可为空的类型,并且没有将它们设置为任何值,则nhibernate将不会在insert或update语句中包含它们。我从来都不喜欢nhibernate更新代码中没有更改的列
此外,当您指定
.Not.Nullable()时在映射中,code>和.Default(“getdate()”)
用于生成架构。nhibernate实际上并没有使用它来进行任何验证或默认设置。这取决于数据库。谢谢,Nullable()
是一个打字错误,我不得不把我的代码精简一点,实际上它有点复杂。你读过关于默认值的文章吗?在映射中定义默认值几乎只用于dml生成(在db中生成默认约束),而不用于在新实例化的实体上定义默认值。这应该通过构造函数或字段初始值设定项来完成,就像任何类一样。+1@Frédéric。这澄清了构造函数的问题。它需要编写一个私有Init()方法并从构造函数中调用它,因为不应该在构造函数中为虚拟道具赋值……谢谢。但有时我需要将值更新为空。我还没有能够以任何方式使.Default(defaultValue)工作-唯一的事情是在MsSql数据库中设置它。或者只将默认值包含到实体中