Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有默认值的DateTime的Fluent NHibernate映射_C#_Sql Server_Nhibernate_Fluent Nhibernate_Fluent Nhibernate Mapping - Fatal编程技术网

C# 具有默认值的DateTime的Fluent NHibernate映射

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

我知道关于这一点有很多线索,我读过其中的大部分。然而,对我来说,有两件事仍然不清楚,仍然不起作用

如果我的数据库架构上有一个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()时
.Default(“getdate()”)
用于生成架构。nhibernate实际上并没有使用它来进行任何验证或默认设置。这取决于数据库。

谢谢,
Nullable()
是一个打字错误,我不得不把我的代码精简一点,实际上它有点复杂。你读过关于默认值的文章吗?在映射中定义默认值几乎只用于dml生成(在db中生成默认约束),而不用于在新实例化的实体上定义默认值。这应该通过构造函数或字段初始值设定项来完成,就像任何类一样。+1@Frédéric。这澄清了构造函数的问题。它需要编写一个私有Init()方法并从构造函数中调用它,因为不应该在构造函数中为虚拟道具赋值……谢谢。但有时我需要将值更新为空。我还没有能够以任何方式使.Default(defaultValue)工作-唯一的事情是在MsSql数据库中设置它。或者只将默认值包含到实体中