I try to map NHibernate to an existing database structure. Unfortunately I can not change the existing structure.
First I'll give some background and then explain the problem itself
Relational analysis is quite simple:
Log is the main Entity. he has one-to-one relationship with Form. the foreign key is FormID.
Buyer & Seller are collection of the form entity. The application should save the form entity together with the buyers and the sellers.
The problem is the primary key consisting of the Buyer & Seller entity. The key composite from ForegineKey- FormID and an intenal ordering int number- tdNum
This is reflected in the following form FNH mapping
public class FormLogMap : ClassMap<FormLog>
{
public FormLogMap()
{
Table("BillOfSaleLog");
Id(x => x.FormId).Column("FormID").GeneratedBy.Native();
....
....
References<Form>(x => x.Form, "FormID").LazyLoad().ReadOnly();
}
}
public class FormMap : ClassMap<Form>
{
public FormMap()
{
Table("BillOfSaleForm");
Id(x => x.Id).Column("FormID").GeneratedBy.Foreign("Log");
开发者_StackOverflow ...
...
HasOne<FormLog>(x => x.Log).Cascade.All();
HasMany(x => x.Buyers).KeyColumn("FormID").Inverse().Cascade.All();
HasMany(x => x.Sellers).KeyColumn("FormID").Inverse().Cascade.All();
}
}
public class BuyerMap : ClassMap<Buyer>
{
public BuyerMap()
{
Table("BillOfSaleBuyer");
CompositeId()
.KeyReference(x => x.Form, "FormID")
.KeyProperty(x => x.InnerOrderId, "tdNum1");
....
....
}
}
Seller is exectly the same
The problem occurs when I try to save the entity by the Edit Action I'm using MVC to get the user data and make it an object. The binding works fine and makes the object along with the collections.
But when I save an entity receive the following error:
I expect NHibernate be smart enough to set the Buyer & Seller foreign keys. But in fact they remain without value.
The problem can be solved by setting foreign keys manually as the following code:
//i have to set the form proerty in the childs
//without of the lines NH will try to save the childs it with FormID = null
foreach (var buyer in form.Buyers) { buyer.Form = form; }
foreach (var seller in form.Sellers) { seller.Form = form; }
But I'm looking for an elegant and correct solution
Thank you for reading
You don't show the code for adding a Buyer or Seller to a Form but it should look like this:
form.Buyers.Add(buyer);
buyer.Form = form;
Because Form is the inverse side of the relationships, you have to set the reference to Form on the many side. You should do this anyway so that the in-memory objects are correct. If the Buyer and Seller objects are already persistent in the same ISession than that should work.
According to this related question, HHibernate does not support cascade working with a composite key (as you have in BuyerMap
). One of the answers does contain a hack to workaround this, but you will end up with a redundant column.
精彩评论