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

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

您应该为SupplierSupplierAddress关系设置一些级联规则:

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 es 或 Supplier s。

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

  1. 一个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);
        }
    }
    
  2. 一个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属性。