【问题标题】:Mapping One to One in FluentNHibernate, NHibernate tries to write child before parent在 FluentNHibernate 中一对一映射,NHibernate 尝试在父级之前写入子级
【发布时间】:2012-07-05 21:51:17
【问题描述】:

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

我查看了http://avinashsing.sunkur.com/2011/09/29/how-to-do-a-one-to-one-mapping-in-fluent-nhibernate/,这似乎证实了这应该可以工作,但是嘿嘿,它一直在尝试将记录插入到父表之前的子表中,这意味着子插入不包含 CustomerId,因为它是外来的键约束。

表格

+------------------------+ +------------------------+ | tbl客户 | | tbl 客户照片 | |-----------------------| |-------------------------| | | 1:1 | | |客户 ID (PK) |+---->|客户 ID (FK) | |其他垃圾... | |照片(图片)| | | | | | | | | +------------------------+ +------------------------+

型号

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();
    }
}

现在 CustomerPhoto 上的外键列设置为非空,我在 CustomerPhotoMapping 的符号中重复了这一点。 在 (https://stackoverflow.com/a/2286491/529120) 的基础上,我将其更改为可为空并从映射中删除符号。

不管怎样,NHibernate 都会返回 System.NullReferenceException : 对象引用未设置为对象的实例。

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

【问题讨论】:

    标签: nhibernate fluent-nhibernate


    【解决方案1】:

    我注意到的几件事

    1. 使用CheckReference 验证此映射可能不正确。我很确定这仅适用于多对一关系。因此,它试图在Customer 之前插入CustomerPhoto 是有道理的。我会在这里使用直接的 NH 会话编写测试。对于我的许多重要映射,我发现使用PersistenceSpecification 比使用它更麻烦。
    2. 一对一映射看起来有点不对劲(建议的解决方案如下)
    3. 将图像列映射到字节数组时,我认为不需要声明自定义类型。下面的映射对我来说效果很好。我认为您在该属性映射上拥有的其他内容是不需要的。

    我有一个与你的几乎相同的映射,这就是我使用的:

    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();
    
        }
    }
    

    【讨论】:

    • 猜这应该是... Id(x => x.Customer.Id) .Column("CustomerID") .GeneratedBy.Foreign("Customer");
    猜你喜欢
    • 2010-10-23
    • 1970-01-01
    • 2011-01-28
    • 2012-01-21
    • 1970-01-01
    • 2012-06-26
    • 2021-05-30
    • 1970-01-01
    • 2010-11-25
    相关资源
    最近更新 更多