1

I currently use a table to store two different types of entities, and distinguish them using a column in the table intTypeId

Entity Company:

       public CompanyMap
       {
            Table("tblTable");
            Id(x => x.Id, "intId");
            Map(x => x.TypeId, "intTypeId");
            Map(x => x.Name, "strCompanyName");
            ...
       }

Entity Person:

       public PersonMap
       {
            Table("tblTable");
            Id(x => x.Id, "intId");
            Map(x => x.TypeId, "intTypeId");
            Map(x => x.Name, "strPersonName");
            ...
       }

I mapped these two models in one table, and it seems to be working well on the webpage, but it breaks some persistence specification tests, throwing exceptions.

The test of Company says that column "strPersonName" cannot be NULL and the test of Person says that the column "strCompanyName" cannot be NULL. If I remove any one map of these two, the test would pass.

Could you please tell me why this happens?

albusshin
  • 3,930
  • 3
  • 29
  • 57

2 Answers2

1

There is a way to do this using a discriminator column, in this case, you could have a base class to map all common columns, for sample:

public class TableMap : ClassMap<Table>
{    
   public TableMap()
   {
      Table("tblTable");

      Id(x => x.Id, "intId");

      // here we specify the name of the column for discriminate types
      DiscriminateSubClassesOnColumn("intTypeId").Not.Nullable();

      Map(x => x.Name, "strCompanyName");      
      // other columns...
   }
}

And after it, you just implement the mapping using the SubclassMap<T>, for each entity, for sample:

public class CompanyMap : SubclassMap<Company>
{
   public CompanyMap()
   {
       DiscriminatorValue(@"Company");  // value for discriminator column
   }
}

public class PersonMap : SubclassMap<Person>
{
   public PersonMap()
   {
       DiscriminatorValue(@"Person");  // value for discriminator column
   }
}

take a look at this article: http://www.codeproject.com/Articles/232034/Inheritance-mapping-strategies-in-Fluent-Nhibernat

albusshin
  • 3,930
  • 3
  • 29
  • 57
Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
  • First of all thanks for your answer. To do this, I need to create a parent class which contains all the columns in the database, and then let class `Company` and class `Person` inherit from it. But I need only a few values instead of all of the columns in my model `Company` and `Person`, and how can I do this? – albusshin Nov 26 '13 at 15:42
  • Well, in this case, I recommend you mapping each class in a single map class instead trying to abstract it to a base classMap. The solution I've shown for you, is to map using a discriminator field using the same table for two or more entities. – Felipe Oriani Nov 27 '13 at 19:10
  • In the article I've posted too, there are other ways to do mapping based on inherits, take a look :) – Felipe Oriani Nov 27 '13 at 19:11
1

Based on this answer, I would give a try to Fluent NH filters

Assuming Company is intTypeId=1 and Person is intTypeId=2 , you may define two filter classes :

public class PersonConditionFilter : FilterDefinition
{
    public PersonConditionFilter()
    {
        WithName("PersonCondition").WithCondition("intTypeId=2");
    }
}

public class CompanyConditionFilter : FilterDefinition
{
    public CompanyConditionFilter()
    {
        WithName("CompanyCondition").WithCondition("intTypeId=1");
    }
}

then you would use these filters in you mappings :

 public PersonMap()
{
    Table("tblTable");
    Id(x => x.Id, "intId");
    Map(x => x.TypeId, "intTypeId");
    Map(x => x.Name, "strPersonName");
    ApplyFilter<PersonConditionFilter>();
}


public CompanyMap ()
{
    Table("tblTable");
    Id(x => x.Id, "intId");
    Map(x => x.TypeId, "intTypeId");
    Map(x => x.Name, "strCompanyName");
    ApplyFilter<CompanyConditionFilter>();
}

finally, don't forget to enable the filters at session level :

session.EnableFilter("CompanyCondition");
session.EnableFilter("PersonCondition");

var persons = session.QueryOver<Person>().List();
var companies = session.QueryOver<Company>().List();
Community
  • 1
  • 1
jbl
  • 15,179
  • 3
  • 34
  • 101
  • Thanks for your answer, but I don't think this would help in my situation of tests failure? – albusshin Nov 27 '13 at 15:56
  • @AlbusShin ok. I would be interested in your tests anyway as I don't see exactly what fails with this approach (which seems less intrusive to me than introducing a hierarchy strategy) – jbl Nov 27 '13 at 16:18