Orchard model inheritance with Table-Per-Concrete-Type?

65 Views Asked by At

I know that the underlying ORM used in Orchard is NHibernate and it does support the so-called ClassMapping which may help customize the mappings the way we want.

However I'm not sure about how Orchard utilizes the mapping methods supported by NHibernate. In this case it seems to always use the strategy similar to Table Per Type in EF as well as some other ORMs. With that strategy, the base class will be mapped to some common table whereas the derived class will be mapped to another table which contains all properties of its own (not declared in the base class). Those 2 tables will have a one-one relationship.

Now I really want to make it use the strategy similar to Table Per Concrete Type in which the base and derived classes will be mapped to 2 different tables with all properties (including inherited properties) being mapped to columns. Those 2 tables will not have any relationship, so querying for columns in just one table will not unexpectedly generate an inner JOIN (for one-one relationship).

Actually that requirement makes sense in case we just need to partition our data (from 1 big table to 2 or more small tables that have the same schema). We don't want to re-declare or use some kind of duplicate model classes (with different names), instead we just need to create a new model class and let it inherit from one base model class containing all necessary properties.

With the current code like this:

public class ARecord {
    //properties ...
}
public class BRecord : ARecord {
    //empty here
}

Currently we cannot use BRecord because it is understood as another part of the ARecord, the auto-generated query (always with INNER JOIN) will be failed because of some does-not-exist table or column names.

How can I solve this?

1

There are 1 best solutions below

7
On

You're not going to like it ;) In a nutshell, the answer is don't do inheritance at all. Orchard was very deliberately designed around the idea of composition, steering well clear of inheritance in its content models. Maybe the central idea in Orchard is to make the concept of content part the "atom of content", and to design those basic units as very simple and composable pieces of functionality that do one thing well.

After all these years, the concept has held remarkably well, and I've yet to see an example of a content model where inheritance would have been more elegant and appropriate. This is reflected in the way nHibernate is customized and used in Orchard, as you've discovered.

So the solution to your problem can likely be one of two things:

  1. You're modeling contents, and you should re-think your approach towards composition of parts. If you give a little more details about your specific scenario (maybe in a new question), I'm happy to help specifically in this direction.
  2. You're modeling non-content data, in which case you might want to consider opting out of Orchard's specific nHibernate content-specialized idiosyncrasies and do things closer to the metal. Again, if you give more specifics about your scenario, I'm happy to take a look and give some pointers.