Nhibernate创建具有对象属性的对象
本文关键字:对象 属性 创建 Nhibernate | 更新日期: 2023-09-27 18:19:37
我刚刚开始使用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'列中
更新 1 映射
供应商地址
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
es 或 Supplier
s。
考虑到这一点,您可能意味着以下两件事之一:
一个
SupplierAddress
由多个Suppliers
共享。这意味着SupplierAddress
实际上有很多Suppliers
,但Supplier
只有一个SupplierAddress
。在 C# 类中,这意味着
SupplierAddress
具有Suppliers
集合(OR 根本没有对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(); } }
请注意,当
Supplier.SupplierAddress
set
时,将设置地址的Supplier
属性。