Fluent NHibernateマッピングをNUnitでテストするとエラーが発生します。問題は、Fluent NHibernateがデータベース内の1 つのオブジェクト ( Contact ) をその子 ( ContactType ) を永続化する前に永続化しようとすると発生するため、外部キー違反が発生します。
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() を使用するようにサプライヤーのマッピングを変更しました。私のマッピングテストの例も提供します。
では、詳細です。
多くの連絡先(1 対多)を持つサプライヤがあります。Contactは、他のテーブルContactTypeと多対 1 の関係にあります。問題に集中できるように、ここではモデルを単純化していることに注意してください。
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テストでは、最初にContactを挿入しようとします ( 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();
}
このテストの結果、この投稿の上部にエラーが表示されます。
よろしくお願いします。必要に応じて詳細を提供することもできます。