I accessing a pre-existing database (actually DB2 on an IBM i), and have an issue with the mappings for the following (simple) structure in Fluent NHibernate. I have had to construct an artificial example, so forgive any ommissions.
Job ...
public class Job
{
public virtual string JobCode { get; set; }
public virtual string Owner{ get; set; }
public virtual IList<Deliverable> Deliverables { get; set; }
public Job()
{
Deliverables = new List<Deliverable>();
}
}
Deliverable ..
public class Deliverable
{
public virtual string JobCode { get; set; }
public virtual int Package { get; set; }
public virtual string Owner { get; set; }
public virtual string Reference { get; set; }
public virtual Job Job { get; set; }
}
I am trying to map a 'HasMany' relationship between Job and Deliverable, as follows ..
public class JobMap : ClassMap<Job>
{
public JobMap()
{
Table("JOB");
Id(x => x.JobCode).Column("CODE");
Map(x => x.Owner).Column("WHODO");
HasMany(x => x.Deliverables)
.KeyColumn("CODE");
}
}
public class DeliverableMap : ClassMap<Deliverable>
{
public DeliverableMap()
{
Table("DELIVERABLE");
Id(x => x.JobCode).Column("CODE");
Map(x => x.Reference).Column("UNQREF");
Map(x => x.Owner).Column("WHODO");
References( x => x.Job)
.Column("CODE") ;
}
}
This seems to work, and if you take the SQL that is produced, and run it directly, the correct results are returned (in this case 11 records, all unique). BUT when I do the following, the list of Deliverables has 11 entries all identical.
IList results = session .CreateCriteria(typeof(Job)) .Add(Expression.Eq("Code", "206171")) .List();
foreach (var job in results)
{
Console.WriteLine("job.JobCode" + job.JobCode);
Console.WriteLine("job.Owner" + job.Owner);
foreach (var deliverable in job.Deliverables)
{
**// These are all identical!**
Console.WriteLine(deliverable.Reference);
Console.WriteLine("deliverable.Owner" + deliverable.Owner);
Console.WriteLine(deliverable.JobNumber);
Console.WriteLine(deliverable.DeliverableTyoe);
Console.WriteLine(deliverable.Description);
}
}
So, are the mappings incorrect, or is there something up with the way that I am using them?
Many thanks in advance, I have been staring at this all day.
I seem to have fixed it. I added CompositeID to the Deliverables mapping
CompositeId()
.KeyProperty(x => x.JobCode, "CODE")
.KeyProperty(x => x.Reference, "UNQREF");
This meant that I had to override the following in the Deliverable class
public override bool Equals(object obj)
{
if (obj == null)
return false;
var t = obj as Deliverable;
if (t == null)
return false;
if (JobCode == t.JobCode && Reference == t.Reference)
return true;
return false;
}
public override int GetHashCode()
{
return (JobCode + "|" + Reference).GetHashCode();
}
and then also changed the Job mapping as below
HasMany(x => x.Deliverables)
.KeyColumn("Codex")
.Inverse()
.Cascade.All();
I am not sure which of these has corrected the situation (I suspect the .Inverse()
in the Job mapping.
I am not sure what the generated SQL now looks like, but the answers look correct.