我在Foo和Bar之间有一对多的关系,我无法执行插入(我到目前为止只尝试过选择和插入...选择似乎工作得很好,每次都插入失败)。
表格定义:
CREATE TABLE [Bar](
[Id] [int] IDENTITY(1,1) NOT NULL,
[DateField] [datetime] NULL,
[StringField] [varchar](8000) NULL
CONSTRAINT [PK_Bar] PRIMARY KEY CLUSTERED([Id] ASC)) ON PRIMARY
CREATE TABLE [Foo](
[Id] [int] IDENTITY(1,1) NOT NULL,
[BarId] [int] NOT NULL,
[DateField] [date] NOT NULL,
[StringField] [varchar](100) NOT NULL,
[GorpId] [int] NOT NULL,
[BoolField] [bit] NOT NULL
CONSTRAINT [PK_Foo] PRIMARY KEY CLUSTERED([Id] ASC))
ALTER TABLE [dbo].[Foo] WITH CHECK ADD CONSTRAINT [FK_Foo_Bar] FOREIGN KEY([BarId])
REFERENCES [dbo].[Bar] ([Id])
GO
课程定义:
public class Foo
{
public virtual int Id { get; set; }
public virtual Bar Bar{ get; set; }
public virtual DateTime DateField{ get; set; }
public virtual string StringField{ get; set; }
public virtual Gorp Gorp{ get; set; }
public virtual bool BoolField{ get; set; }
}
public class Bar
{
public virtual int Id { get; set; }
public virtual DateTime DateField{ get; set; }
public virtual string StringField{ get; set; }
public virtual ICollection<Foo> Foos{ get; set; }
public Bar()
{
Foos= new List<Foo>();
}
public virtual void AddFoo(Foo foo)
{
foo.Bar = this;
Foos.Add(foo);
}
}
映射:
public class FooMap : ClassMap<Foo>
{
public FooMap()
{
Id(x => x.Id).UnsavedValue(0).GeneratedBy.Identity();
Map(x => x.DateField);
Map(x => x.BoolField);
Map(x => x.StringField);
References(x => x.Gorp)
.Column("GorpId")
.Class<Gorp>();
References(x => x.Bar)
.Column("BarId")
.Not.Nullable();
}
}
public class BarMap : ClassMap<Bar>
{
Id(x => x.Id).UnsavedValue(0).GeneratedBy.Identity();
Map(x => x.DateField);
Map(x => x.StringField);
HasMany<Foo>(x => x.Foos)
.AsBag()
.Cascade.SaveUpdate()
.ForeignKeyConstraintName("FK_Foo_Bar")
.Inverse()
.KeyColumn("BarId")
.Not.KeyNullable();
}
生成的XML:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="MyApp.Domain.Model.Bar, MyApp.Domain, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null" table="`Bar`">
<id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
<column name="Id" />
<generator class="identity" />
</id>
<property name="DateField" type="System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="DateField" />
</property>
<property name="StringField" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="StringField" />
</property>
<bag cascade="save-update" inverse="true" name="Foos" mutable="true">
<key foreign-key="FK_Foo_Bar" not-null="true">
<column name="BarId" />
</key>
<one-to-many class="MyApp.Domain.Model.Foo, MyApp.Domain, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null" />
</bag>
</class>
</hibernate-mapping>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="MyApp.Domain.Model.Foo, MyApp.Domain, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null" table="`Foo`">
<id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
<column name="Id" />
<generator class="identity" />
</id>
<property name="DateField" type="System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="DateField" />
</property>
<property name="BoolField" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="BoolField" />
</property>
<property name="StringField" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="StringField" />
</property>
<many-to-one class="MyApp.Domain.Model.Gorp, MyApp.Domain, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null" name="Gorp">
<column name="GorpId" />
</many-to-one>
<many-to-one class="MyApp.Domain.Model.Bar, MyApp.Domain, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null" insert="false" name="Bar" update="false">
<column name="BarId" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
例外:
无法插入:[MyApp.Domain.Model.Foo] [SQL:INSERT INTO [Foo](DateField,BoolField,StringField,GorpId,BarId)VALUES(?,?,?,?,?);选择SCOPE_IDENTITY()]
我缺少什么/误会?
答案 0 :(得分:1)
谢谢你,戴夫,指出我正确的方向。其中一个Date字段在数据库中可以为空,另一个则不是。我改变了我的课程和地图来反映这一点。瞧!它奏效了!
原始错误消息太糟糕没告诉我日期时间字段存在问题,这会让我感到头疼。
我做了以下更改:
public class Foo
{
public virtual int Id { get; set; }
public virtual Bar Bar{ get; set; }
public virtual DateTime DateField{ get; set; }
public virtual string StringField{ get; set; }
public virtual Gorp Gorp{ get; set; }
public virtual bool BoolField{ get; set; }
public Foo()
{
DateField = new DateTime(1753, 1, 1);
}
}
public class Bar
{
public virtual int Id { get; set; }
public virtual DateTime? DateField{ get; set; }
public virtual string StringField{ get; set; }
public virtual ICollection<Foo> Foos{ get; set; }
public Bar()
{
DateField = new DateTime(1753, 1, 1);
Foos= new List<Foo>();
}
public virtual void AddFoo(Foo foo)
{
foo.Bar = this;
Foos.Add(foo);
}
}
public class FooMap : ClassMap<Foo>
{
public FooMap()
{
Id(x => x.Id).UnsavedValue(0).GeneratedBy.Identity();
Map(x => x.DateField);
Map(x => x.BoolField);
Map(x => x.StringField);
References(x => x.Gorp)
.Column("GorpId")
.Class<Gorp>();
References(x => x.Bar)
.Column("BarId")
.Not.Nullable();
}
}
public class BarMap : ClassMap<Bar>
{
Id(x => x.Id).UnsavedValue(0).GeneratedBy.Identity();
Map(x => x.DateField)
.Nullable();
Map(x => x.StringField);
HasMany<Foo>(x => x.Foos)
.AsBag()
.Cascade.SaveUpdate()
.Fetch.Join()
.ForeignKeyConstraintName("FK_Foo_Bar")
.Inverse()
.KeyColumn("BarId")
.Not.KeyNullable()
.Table("Foo");
}
答案 1 :(得分:0)
如果在创建新对象时未显式初始化属性,则它将接收默认值。对于datetime,该默认值为datetime.minvalue。
datetime.minvalue是一个比sql server允许的更早的日期。这是一个可憎的原因.net和sql server不支持相同的日期时间范围,但它是如何实现的。当您尝试将datetime.minvalue插入sql server时,您将看到您所看到的异常。
修复方法是始终为新对象提供该属性的值,在该数据库中为该列创建默认值,或使datatime属性可为空(DateTime?)。
这实际上与您的类的关系没有任何关系,只是与使用默认值的非初始化的非可空日期时间属性有关。