流畅的NHibernate一对多无法插入(外键约束)

时间:2012-05-02 14:24:47

标签: fluent-nhibernate nunit one-to-many

使用 NUnit 测试 Fluent NHibernate 映射时出错。当Fluent NHibernate试图在持久化它的子( ContactType )之前在数据库中持久保存一个对象( Contact )时出现问题,从而给我一个外键违规:

NHibernate.Exceptions.GenericADOException : could not insert: Contact [...]
----> System.Data.SqlClient.SqlException : The INSERT statement conflicted with 
the FOREIGN KEY constraint [...] with table ContactType

编辑:修改了供应商的映射,以便在HasMany()上使用Inverse()。还提供了我的映射测试示例。

现在,细节。

我有一个供应商,其中包含许多联系人(一对多)。 联系人与其他表 ContactType 具有多对一关系。请记住,我在这里简化了模型,因此我们可以专注于解决问题。

public class SupplierMap : ClassMap<Supplier>
{
        public SupplierMap() 
        {
            Table("Supplier");
            LazyLoad();
            Id(x => x.Id).GeneratedBy.Identity().Column("id");
            HasMany(x => x.Contacts).KeyColumn("supplierId").Cascade.All().Inverse();
        }
}
public class ContactMap : ClassMap<Contact> 
{
    public ContactMap() 
    {
        Table("Contact");
        LazyLoad();
        Id(x => x.Id).GeneratedBy.Identity().Column("id");
        References(x => x.ContactType).Column("contactTypeId");
        References(x => x.Supplier).Column("supplierId").Cascade.All();
    }
}
public class ContactTypeMap : ClassMap<ContactType> 
{

    public ContactTypeMap() {
        Table("ContactType");
        LazyLoad();
        Id(x => x.Id).GeneratedBy.Identity().Column("id");
    }
}

现在,当我测试 ContactMap 时,测试运行得很好,没有错误。但是,当我运行SupplierMap测试时,这就是我收到错误的地方。正如预期的那样,当我运行ContactMap测试时,我在跟踪中得到了类似的内容:

INSERT INTO ContactType [...]
INSERT INTO Contact [...]
SELECT [...]
[...]

ContactMap测试:

[Test]
    public void CanCorrectlyMapContact()
    {
        new PersistenceSpecification<Contact>(Session)
    .CheckProperty(c => c.Id, 1)
    .CheckReference(c => c.ContactType, new ContactType() { Id = 1, Archived = false, DescriptionEn = Constants.LOREM_IPSUM_255, DescriptionFr = Constants.LOREM_IPSUM_255, NameEn = Constants.LOREM_IPSUM_50, NameFr = Constants.LOREM_IPSUM_50 })
    .CheckReference(c => c.Title, new Title() { Id = 1, Archived = false, NameEn = Constants.LOREM_IPSUM_255, NameFr = Constants.LOREM_IPSUM_255, SortOrder = 0})
    .CheckReference(c => c.Region, new Region() { Id = 1, Archived = false, NameEn = Constants.LOREM_IPSUM_128, NameFr = Constants.LOREM_IPSUM_128, SortOrder = 0 })
    .VerifyTheMappings();
    }

对于 SupplierMap 测试,我首先尝试插入联系人(不尝试插入 ContactType )。

SupplierMap测试:

[TestFixture]
public class SupplierMapTest : DatabaseSetup
{
    private IList<Contact> tmpList;

    public SupplierMapTest()
   {
       Contact tmpContact = new Contact()
       {
           Id = 1,
           FirstName = Constants.LOREM_IPSUM_128,
           LastName = Constants.LOREM_IPSUM_128,
           Address = Constants.LOREM_IPSUM_128,
           City = Constants.LOREM_IPSUM_128,
           Email = Constants.LOREM_IPSUM_128,
           FaxNumber = Constants.PHONE_NUMBER_50,
           PhoneNumber = Constants.PHONE_NUMBER_50,
           PostalCode = Constants.POSTAL_CODE_10,
           Archived = false
       };
       tmpContact.ContactType = new ContactType { Id = 1, Archived = false, DescriptionEn = Constants.LOREM_IPSUM_255, DescriptionFr = Constants.LOREM_IPSUM_255, NameEn = Constants.LOREM_IPSUM_50, NameFr = Constants.LOREM_IPSUM_50 };
       this.tmpList = new List<Contact>();
       this.tmpList.Add(tmpContact);
   }

    /// <summary>
    /// Verify if the maping is successfull
    /// </summary>
    [Test]
    public void CanCorrectlyMapSupplier()
    {

        new PersistenceSpecification<Supplier>(Session)
        .CheckProperty(x => x.Id, 1)
        .CheckList(x => x.Contacts, this.tmpList)
        .VerifyTheMappings();
    }

此测试导致此帖子顶部出现错误。

提前感谢您的帮助。如果需要,我还可以提供更多细节。

1 个答案:

答案 0 :(得分:0)

HasMany(x => x.Contacts).KeyColumn("supplierId").Inverse();

有关详细信息,请参阅here