在FluentNHibernate中映射一对一,NHibernate尝试在父级之前写入子级

在FluentNHibernate中映射一对一,NHibernate尝试在父级之前写入子级,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我试图在FN中建立1:1的关系,但这有点痛苦 我看了一下,这似乎证实了这一点,但嘿,呵呵,它一直试图在父表之前将记录插入子表,这意味着子插入不包含作为外键约束所需的CustomerId 桌子 地图 测验 现在CustomerPhoto上的外键列被设置为notnull,我在CustomerPhotoMapping上的注释中重复了这一点。 在此基础上,我将其更改为nullable,并从映射中删除了符号 无论哪种情况,NHibernate都会返回 System.NullReferenceExcepti

我试图在FN中建立1:1的关系,但这有点痛苦

我看了一下,这似乎证实了这一点,但嘿,呵呵,它一直试图在父表之前将记录插入子表,这意味着子插入不包含作为外键约束所需的CustomerId

桌子 地图 测验 现在CustomerPhoto上的外键列被设置为notnull,我在CustomerPhotoMapping上的注释中重复了这一点。 在此基础上,我将其更改为nullable,并从映射中删除了符号

无论哪种情况,NHibernate都会返回 System.NullReferenceException:对象引用未设置为对象的实例

并且似乎试图首先插入CustomerPhoto记录,将零作为CustomerId传递;然后创建客户记录,然后尝试使用左侧外部连接选择客户和照片。这显然不起作用,因为它从未试图更新照片表中的ID。

我注意到的几件事

使用CheckReference验证此映射可能不正确。我很确定这只适用于多对一关系。因此,它尝试在客户之前插入CustomerPhoto是有意义的。我将在这里使用直接的NH会话编写一个测试。我发现对我的许多映射使用PersistenceSpecification比它的价值要麻烦得多。 一对一映射看起来有点偏离下面提出的解决方案 在将图像列映射到字节数组时,我认为不需要声明自定义类型。下面的映射对我来说很好。我认为你在属性映射上的其他东西是不需要的。 我有一个与你的几乎相同的映射,这就是我使用的:

public class Customer 
{
  public virtual int CustomerID { get; private set; }
  public virtual CustomerPhoto CustomerPhoto { get; set; }
  /* public virtual Other crap */

}

public class CustomerPhoto
{
  public virtual Customer Customer { get; set; }
  public virtual Byte[] Photograph { get; set; }
}

public class CustomerPhotoMap : ClassMap<CustomerPhoto>
{
    public CustomerPhotoMap()
    {
        Id(x => x.Id)
            .Column("CustomerID")
            .GeneratedBy.Foreign("Customer");

        Map(x => x.Photograph).Length(Int32.MaxValue);
    }
}

public class CustomerMap : ClassMap<Customer>
{
    public CustomerMap()
    {

        Id(x => x.CustomerID).GeneratedBy.Identity()
            .Column("CustomerID");

        HasOne(x => x.CustomerPhoto)
            .Cascade.All();

    }
}

我猜这应该是。。。Idx=>x.Customer.Id.ColumnCustomerID.GeneratedBy.ForeignCustomer;
public class Customer 
{
    public virtual int CustomerID { get; private set; }
    /* public virtual Other stuff */
}

public class CustomerPhoto
{
    public virtual int CustomerID { get;set;}
    public virtual Byte[] Photograph { get; set; }
}
public class CustomerPhotoMap : ClassMap<CustomerPhoto>
{
    public CustomerPhotoMap()
    {
        Id(x => x.CustomerID)
            .Column("CustomerID")
            .GeneratedBy.Assigned();

        Map(x => x.Photograph)
            .CustomSqlType("Image")
            .CustomType<Byte[]>()
            .Nullable();
    }
}

public class CustomerMap : ClassMap<Customer>
{
    public CustomerMap()
    {

        Id(x => x.CustomerID)
            .GeneratedBy.Identity()
            .Column("CustomerID");
        HasOne<CustomerPhoto>(x => x.CustomerPhoto)
            .LazyLoad()
            .ForeignKey("CustomerID");
    }
}
class CustomerMappingFixture : IntegrationTestBase
{
    [Test]
    public void CanMapCustomer()
    {
        new PersistenceSpecification<Customer>(Session)
            .CheckReference(x => x.CustomerPhoto, new CustomerPhoto(){ Photograph = Arrange.GetBitmapData(ImageFormat.Jpeg) })
            .VerifyTheMappings();
    }
}
public class Customer 
{
  public virtual int CustomerID { get; private set; }
  public virtual CustomerPhoto CustomerPhoto { get; set; }
  /* public virtual Other crap */

}

public class CustomerPhoto
{
  public virtual Customer Customer { get; set; }
  public virtual Byte[] Photograph { get; set; }
}

public class CustomerPhotoMap : ClassMap<CustomerPhoto>
{
    public CustomerPhotoMap()
    {
        Id(x => x.Id)
            .Column("CustomerID")
            .GeneratedBy.Foreign("Customer");

        Map(x => x.Photograph).Length(Int32.MaxValue);
    }
}

public class CustomerMap : ClassMap<Customer>
{
    public CustomerMap()
    {

        Id(x => x.CustomerID).GeneratedBy.Identity()
            .Column("CustomerID");

        HasOne(x => x.CustomerPhoto)
            .Cascade.All();

    }
}