1
votes

I'm having difficulty mapping a database using Fluent NHibernate. The database I'm working on is brownfield and some of the relationships are poorly implemented.

The mapping I'm trying to do is described by the following tables:

+----------+ +----------+ +---------------+  +-------------------+
| ToolA    | | ToolB    | | ToolPurpose   |  | ToolInstruction   |
+==========+ +==========+ +===============+  +===================+
| ToolA_Id | | ToolB_Id | | Purpose_Id    |  | ToolInstruction_Id|
| Name     | | Name     | | ToolA_Id      |  | Purpose_Id        |
+----------+ +----------+ | ToolB_Id      |  | Instruction       |
                          | Purpose       |  +-------------------+
                          +---------------+

What I'm looking to do is to map the table ToolA with the table ToolInstruction to get a class such as:

public class ToolA
{
    public virtual int _ToolA_id { get; set; }
    public virtual string _Name { get; set; }
    public virtual string _Instruction { get; set; }
}

OR

public class ToolA
{
    public virtual int _ToolA_id { get; set; }
    public virtual string _Name { get; set; }
    public virtual ToolInstruction _ToolInstruction{ get; set; }
}

public class ToolInstruction
{
    public virtual string _Instruction { get; set; }
}

What I think is causing me difficulty is that the ToolPurpose table has a row for every ToolA and ToolB entry such that for a ToolA entry the ToolB_Id is null and vice versa.

For example:

+--------------------------------------------------+
|Purpose_Id | ToolA_Id | ToolB_Id | Purpose        |
|===================================================
|1          | 1        | null     | "purpose here" |
|2          | null     | 1        | "purpose here" |
+--------------------------------------------------+

I've tried a few approaches to this and they have shown signs of working when using the PersistenceSpecification.VerifyTheMappings() method but not when I've tried pulling data from a backup database because I start running into null reference exceptions.

I've tried mapping ToolPurpose as a linker class and I've tried mapping it by using the Join method in the ToolA mapping class. I've also alternated between using HasOne and HasMany to see which was suitable.

I'm hoping someone can point me in the right direction by laying out how they would do it or if they see any problems in terms of how I'm approaching it.

2
Are you able to change the DB as well as your domain objects, or is that a fixed point?docmanhattan

2 Answers

1
votes

u can use this for part of the your question:

ToolA
------
ToolBs = new Dictionary<string, ToolB>();
public virtual IDictionary<string, ToolB> ToolBs { get; set; }

HasManyToMany<ToolB>(x => x.ToolBs)
                .Table("ToolPurpose")
                .ChildKeyColumn("ToolB_Id ")
                .ParentKeyColumn("ToolA_Id")
                .AsMap<string>("Purpose")
                .Cascade.All();
0
votes

I'm working without any documentation for the database I'm mapping and it turns out this was where my difficulty arose. The ToolPurpose to ToolA relationship is actually a many to one relationship such that each tool has multiple purposes and the ToolPurpose to ToolInstruction relationship is also a many to one relationship such that each purpose can have multiple instructions related to it.

This means a straight forward HasMany() <-> References() mappings can be used to link the ToolA, ToolPurpose and ToolInstruction tables together. The null values in the ToolPurpose table do not affect the mappings in this way.

I should have mentioned in my openbing post that I'm just extracting and not updating or saving to the database so I do not need a complete mapping of the tables so I don't have to map ToolB.