0
votes

I'm currently trying to get (Fluent)NHibernate to map an object to our legacy database schema. There are three tables involved.

  • Table a contains most information of the actual object I need to retrieve
  • Table b is a table which connects table a with table c
  • Table c has one additional field I need for the object

An SQL query to retrieve the information looks like this:

SELECT z.ID, z.ZANR, e.TDTEXT 
FROM   PUB.table_a z 
JOIN   PUB.table_b t ON (t.TDKEY = 602) 
JOIN   PUB.table_c e ON (e.ID = t.ID AND e.TDNR = z.ZANR) 
WHERE  z.ZANR = 1;

The main problem is how to specify these two join conditions in the mapping.

Entity for table a looks like this:

public class EntityA
{
    public virtual long Id { get; set; }
    public virtual int Number { get; set; }
    public virtual string Name { get; set; }
}

Name should map to the column table_c.TDTEXT.

The mapping I have so far is this:

public class EntityAMap : ClassMap<EntityA>
{
    public EntityAMap()
    {
        Table("PUB.table_a");
        Id(x => x.Id).Column("ID");
        Map(x => x.Number).Column("ZANR");
    }
}

I tried to map the first join with the same strategy as in How to join table in fluent nhibernate, however this will not work, because I do not have a direct reference from table_a to table_b, the only thing connecting them is the constant number 602 (see SQL-query above).

I didn't find a way to specify that constant in the mapping somehow.

1
What do your entities look like? What mapping have you tried so far? - Paul Turner

1 Answers

0
votes

you could map the name as readonly property easily

public EntityAMap()
{
    Table("PUB.table_a");

    Id(x => x.Id).Column("ID");

    // if ZANR always has to be 1
    Where("ZANR = 1");

    Map(x => x.Number).Column("ZANR");
    Map(x => x.Name).Formula("(SELECT c.TDTEXT FROM PUB.table_b b JOIN PUB.table_c c ON (c.ID = b.ID AND b.TDKEY = 602 AND c.TDNR = ZANR))");
}

Update: i could only imagine a hidden reference and the name property delegating to there

public EntityAMap()
{
    HasOne(Reveal.Member<EntityA>("hiddenEntityC"));
}

public class EntityB
{
    public virtual int Id { get; set; }
    public virtual EntityA EntityA { get; set; }
}

public EntityCMap()
{
    Where("Id = (SELECT b.Id FROM PUB.table_b b WHERE b.TDKEY = 602)");

    References(x => x.EntityA).PropertyRef(x => x.Number);
}