Search code examples
c#nhibernatefluent-nhibernate

NHibernate: Same type, different ClassMaps?


I have a use case where the same type is used in different one-to-many relationships, and the data on the many side of the relationship has to be stored to different tables depending on the usage. Is there a way I can tell (fluent) NHibernate which ClassMap to use (e.g. like my fake UseClassMap method below)?

Rough example code:

public class Foo
{
  public long Id {get; set;}
  public IEnumerable<Bar> TheoreticalBar {get; set;}
  public IEnumerable<Bar> ActualBar {get; set; }
}

public class FooMap : ClassMap<Foo>
{
  Table("Foo");
  Id(x => x.Id);
  HasMany(x => x.TheoreticalBar).UseClassMap(TheoryBarMap);
  HasMany(x => x.ActualBar).UseClassMap(ActualBarMap); 
}

public class TheoreticalBarMap : ClassMap<Bar>
{
  TableNames("TheoreticalBar");
  ...
}

public class ActualBarMap : ClassMap<Bar>
{
  TableNames("ActualBar");
  ...
}


Solution

  • In the hopes of garnering more arbitrary and unexplained downvotes, I'll answer this question: I wasn't able to find a specific method to explicitly declare the ClassMap to use, but I was able to find a solution without adding unncessary subtypes or similar ClassMaps by adding a discriminator value to the child class that is set by the parent, and then using the .Where() method to filter on the discriminator value ... something like this:

    class Bar
    {
      public string BarType {get; protected set};
    
      public Bar(string barType)
      {
        BarType = barType;
      }
    }
    
    public class FooMap : ClassMap<Foo>
    {
      Table("Foo");
      Id(x => x.Id);
      HasMany(x => x.TheoreticalBar).Where("BarType = theoretical");
      HasMany(x => x.ActualBar).Where("BarType = actual"); 
    }
    

    The .Where() method allows use of string interpolation and substitutions in case you want to avoid magic strings in my simplistic example here.