我知道有很多线索,我已经阅读了大部分内容。但对我来说有些事情仍然不清楚仍然无效。
如果我的数据库模式上有一个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 .Fluent配置适用于SQL Server 2012.)
从ISQL执行INSERT
时,这样可以正常工作,插入添加记录时的时间戳。
使用流利的我会写这样的东西:
域:
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 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);
...
但这不是解决方案......
问题:
我为字段CUser
执行此操作,因为在CUser
我想添加当前用户上下文
public MyObject()
{
var o = System.Security.Principal.WindowsIdentity.GetCurrent();
if (o != null)
{
CUser = o.Name;
}
}
我没有在我的数据库访问层库中填入当前日期的CDate字段,而是在域类的构造函数中也可以这样做:
public MyObject()
{
var o = System.Security.Principal.WindowsIdentity.GetCurrent();
if (o != null)
{
CUser = o.Name;
}
CDate = DateTime.Now;
}
非常感谢您的帮助和评论!
答案 0 :(得分:3)
通常对于这种类型的映射,我在映射中执行以下操作:
DynamicInsert();
DynamicUpdate();
这种方式如果你在C#中有可空类型并且你没有将它们设置为任何东西,那么nhibernate将不会在insert或update语句中包含它们。当nhibernate正在更新代码中未更改的列时,我从不喜欢它。
此外,当您在映射中指定.Not.Nullable();
和.Default("getdate()")
时,所有这些都用于模式生成。它实际上并不是由nhibernate用来进行任何验证或默认。这取决于数据库。
答案 1 :(得分:1)
您已在数据库中将此列定义为NOT NULL
,并在映射中将其定义为Nullable()
。 FluentNHibernate正在向数据库发送DbNull
,因为数据库列不可为空而被拒绝。
您应该决定逻辑所在的位置。这是您的代码还是主数据库?
例如,在this question中讨论了在FlientNHibernate中设置默认值。
建议的代码是:
Map(x => x.SubmitionDate).Default("getdate()").Not.Nullable();
一般情况下,我总是建议使用NHibernate Profiler(付费工具)来查看哪些查询进入数据库以及它们失败的原因。非常有利于优化,您正在使用ORM,现在要小心!