I have a one-to-one relationship in my db and I seem to be having issues with my fluent nhibernate mapping of this relationship.
When I attempt to insert a new TableA entity I receive the following error: "unable to resolve property: TableA". The error is thrown on this line in the repository: int id = (int)_session.Save(item);
Repository code:
public T Save(T item)
{
try
{
_session.BeginTransaction();
int id = (int)_session.Save(item);
_session.Transaction.Commit();
return _session.Get<T>(id);
}
catch (Exception)
{
_session.Transaction.Rollback();
throw;
}
}
Table definitions:
Table A
Id (int, pk, identity)
Field1 (nvarchar)
Field2 (date)
...
Table B
TableAId (int, pk) <-- no fk constraint on these tables
Field1 (nvarchar)
Field2 (nvarchar)
Field3 (bit)
Classes:
public class TableA
{
public virtual int Id {get;set;}
public virtual string Field1 {get;set;}
public virtual DateTime Field2 {get;set;}
public virtual TableB TableB {get;set;}
}
public class TableB
{
public virtual int TableAId {get;set;}
public virtual string Field1 {get;set;}
public virtual string Field2 {get;set;}
}
Mapping:
public class TableAMap : ClassMap<TableA>
{
public TableAMap(){
Id(x => x.Id);
Map(x => x.Field1);
Map(x => x.Field2);
HasOne(x => x.TableB)
.Cascade.SaveUpdate()
.Fetch.Join();
}
}
public class TableBMap : ClassMap<TableB>
{
public TableBMap()
{
Id(x => x.Id, "TableAId").GeneratedBy.Foreign("TableA");
Map(x => x.Field1);
Map(x => x.Field2);
Map(x => x.Field3);
}
}
I used these as a reference: http://avinashsing.sunkur.com/2011/09/29/how-to-do-a-one-to-one-mapping-in-fluent-nhibernate/
One-to-one Mapping issue with NHibernate/Fluent: Foreign Key not updateing
IndexOutOfRangeException Deep in the bowels of NHibernate
I've been looking at this for so long now I fear I'm missing something simple (and stupid).
Update: Tried this:
public class TableA
{
public virtual int Id {get;set;}
public virtual string Field1 {get;set;}
public virtual DateTime Field2 {get;set;}
public virtual TableB TableB {get;set;}
public virtual int TableBId
{
get{return TableB.Id;}
set{}
}
}
public class TableAMap : ClassMap<TableA>
{
public TableAMap()
{
Id(x => x.Id);
Map(x => x.Field1);
Map(x => x.Field2);
HasOne<TableB>(x => x.TableB)
.Cascade.SaveUpdate()
.Fetch.Join()
.ForeignKey("TableBId");
}
}
public class TableBMap : ClassMap<TableB>
{
public TableBMap()
{
Id(x => x.Id, "TableAId");
Map(x => x.Field1);
Map(x => x.Field2);
Map(x => x.Field3);
}
}
I didn't get the "unable to resolve property: TableA" error this time, but I received a different error. It seems like the Id of the TableA record did not cascade to the TableB record.
Did some more reading.
Found this post: fluent NHibernate one-to-one relationship?
Made some more changes:
public class TableAMap : ClassMap<TableA>
{
public TableAMap()
{
Id(x => x.Id);
Map(x => x.Field1);
Map(x => x.Field2);
HasOne<TableB>(x => x.TableB)
.Cascade.All()
.Constrained()
.Fetch.Join()
.ForeignKey("TableBId");
}
}
public class TableBMap : ClassMap<TableB>
{
public TableBMap()
{
Id(x => x.Id, "TableAId").UnsavedValue(0).GeneratedBy.Foreign("TableA");
Map(x => x.Field1);
Map(x => x.Field2);
Map(x => x.Field3);
HasOne<TableA>(x => x.TableA);
}
}
New error: "attempted to assign id from null one-to-one property: TableA"