Nhibernate创建具有对象属性的对象

时间:2014-08-26 14:10:32

标签: c# nhibernate fluent-nhibernate

我刚刚开始使用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映射

for SupplierAddress


        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");

1 个答案:

答案 0 :(得分:2)

您应该在SupplierSupplierAddress关系中设置一些cascade rules

References(s => s.SupplierAddress)
    .Column("SupplierAddressId")
    .Not.Nullable()
    .Cascade.All(); /* Cascade operations that happen on `Supplier` */

否则,NHibernate不知道保存父(Supplier)也应该保存孩子(SupplierAddress

修改:我认为您实际上在这里错误地使用了References

在映射中,当你说另一个实体References时,你基本上告诉NHibernate 这段关系的另一面是HasMany

在您的情况下,SupplierSupplierAddress实际上分别没有SupplierAddress个或Supplier个。

考虑到这一点,你可能意味着两件事之一:

  1. 多个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);
        }
    }
    
  2. Supplier只有一个SupplierAddressSupplierAddress只与一个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.SupplierAddressset时,地址的Supplier属性已设置。