[英]Nhibernate creating object which has an object property
我刚刚开始使用NHibernate。 我有两个对象:
public class Supplier
{
public virtual int id{get;set;}
public virtual SupplierAddress address{get;set;}
public virtual string Name{get;set;}
}
public class SupplierAddress
{
public virtual int id{get;set;}
public virtual Supplier{get;set;}
public virtual string SupplierAddressLine{get;set;}
}
当我想创建一个新的Supplier
我创建了一个新的对象:
var supplierAddress = new SupplierAddress {
SupplierAddressLine = "someLine"
}
var supplier = new Supplier
{
Name = "someName",
SupplierAddress = SupplierAddressLine
}
然后,当我尝试使用以下方法进行保存时:
_session.Save(supplier);
我收到错误消息:“无法将值NULL插入列'id'
供应商地址
Id(x => x.Id).GeneratedBy.Identity().Column("Id");
References(x => x.Supplier).Column("SupplierId");
Map(x => x.AddressLine1).Column("AddressLine1").Not.Nullable().Length(255);
供方
Id(x => x.Id).GeneratedBy.Identity().Column("Id");
References(x => x.SupplierAddress).Column("SupplierAddressId").Not.Nullable();
HasMany(x => x.SupplierAddresses).KeyColumn("SupplierId");
您应该在Supplier
→ SupplierAddress
关系上设置一些级联规则 :
References(s => s.SupplierAddress)
.Column("SupplierAddressId")
.Not.Nullable()
.Cascade.All(); /* Cascade operations that happen on `Supplier` */
否则,NHibernate不知道保存父级( Supplier
)也应保存子级( SupplierAddress
)
编辑:我认为您实际上在这里错误地使用了References
。
在映射中,当您说一个实体References
另一个实体时,您基本上是在告诉NHibernate 这种关系的另一面是HasMany
。
在您的情况下, Supplier
和SupplierAddress
实际上都没有分别具有多个SupplierAddress
或Supplier
。
考虑到这一点,您可能意味着两件事之一:
一个SupplierAddress
由多个Suppliers
共享。 这将意味着SupplierAddress
实际上有许多 Suppliers
,但一个Supplier
只有一个SupplierAddress
。
在C#类中,这意味着SupplierAddress
具有一个Suppliers
集合(或完全没有对Supplier
引用)。
在这种情况下,您的数据库表将如下所示:
create table [SupplierAddress] ( [Id] int identity(1,1) primary key clustered, [AddressLine1] nvarchar(255) not null ); create table [Supplier] ( [Id] int identity(1,1) primary key clustered, [SupplierAddressId] int not null references [SupplierAddress]([Id]) )
您的C#类如下所示:
public class Supplier { public virtual int Id { get; set; } public virtual SupplierAddress SupplierAddress { get; set; } public virtual string Name { get; set; } } public class SupplierAddress { public virtual int Id { get; set; } public virtual string AddressLine1 { get; set; } }
您的映射如下所示:
public class SupplierMap : ClassMap<Supplier> { public SupplierMap() { Id(s => s.Id).GeneratedBy.Identity().Column("Id"); References(s => s.SupplierAddress) .Column("SupplierAddressId") .Cascade.All(); } } public class SupplierAddressMap : ClassMap<SupplierAddress> { public SupplierAddressMap() { Id(s => s.Id).GeneratedBy.Identity().Column("Id"); Map(s => s.AddressLine1) .Column("AddressLine1") .Not.Nullable() .Length(255); } }
Supplier
有一个SupplierAddress
,而SupplierAddress
仅与一个Supplier
相关联。 另一种思考方式是,整个SupplierAddress
表可以在逻辑上合并到Supplier
。
在这种情况下,您的数据库表将如下所示:
create table [SupplierAddress] ( [Id] int identity(1,1) primary key clustered, [AddressLine1] nvarchar(255) not null, [SupplierId] int not null ); create table [Supplier] ( [Id] int identity(1,1) primary key clustered, [SupplierAddressId] int references [SupplierAddress]([Id]) ); alter table [SupplierAddress] add constraint [FK_SupplierAddress_Supplier] foreign key ([SupplierId]) references [Supplier]([Id])
您的C#类如下所示:
public class Supplier { private SupplierAddress supplierAddress; public virtual int Id { get; set; } public virtual SupplierAddress SupplierAddress { get { return this.supplierAddress; } set { this.supplierAddress = value; this.supplierAddress.Supplier = this; } } public virtual string Name { get; set; } } public class SupplierAddress { public virtual int Id { get; set; } public virtual string AddressLine1 { get; set; } public virtual Supplier Supplier { get; set; } }
您的映射如下所示:
public class SupplierMap : ClassMap<Supplier> { public SupplierMap() { Id(s => s.Id).GeneratedBy.Identity().Column("Id"); HasOne(s => s.SupplierAddress).PropertyRef(s => s.Supplier) .Access.CamelCaseField() .Cascade.All(); } } public class SupplierAddressMap : ClassMap<SupplierAddress> { public SupplierAddressMap() { Id(s => s.Id).GeneratedBy.Identity().Column("Id"); Map(s => s.AddressLine1).Column("AddressLine1"); References(s => s.Supplier).Column("SupplierId").Unique(); } }
请注意,当set
Supplier.SupplierAddress
时,将set
地址的Supplier
属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.