Mapping a derived class

Topics: Core, General, Troubleshooting
Oct 29, 2013 at 10:09 AM
I'm try to migrate two parent-child classes:

public class ARecord
{
public virtual int Id { get; set; }
public virtual string name{ get; set; }
}

public class BRecord : ARecord
{
public virtual string description { get; set; }
}

However the migration is generating only the ARecord table, no trace of the other table.
I also tried to add the "new" keyword for the "description" properties. Further I tried to add
a
"public virtual ARecord ARecord { get; set; }"

property in the BRecord class, no way. Which is the correct way to handle derived class mapping?

Thanks.
Coordinator
Oct 30, 2013 at 7:41 AM
Orchard massively prefers composition over inheritance. Mapping derived classes is not supported as far as I know. Please explain the scenario, and we can show you how to implement it correctly. If this really is your scenario, there is no reason for BRecord to derive from ARecord. Just compose content types that have the parts corresponding to A, B, or both.
Oct 1, 2014 at 12:04 AM
The Orchard approach is to build bigger classes by welding smaller ones (composition).
For more information see http://www.codeproject.com/Articles/434484/Welding-on-Orchard-CMS or just google "Orchard" and "Weld"

This concept is very flexible. It allows managing types from the UI and has some other benefits.
If you are in the process of getting into Orchard (as I am) I would suggest that you learn to use this concept and not try to force inheritance for parts etc. It is important to learn this for understanding Orchard and for utilizing its power in your own projects.

I can say that it took me some time to get used to it. Inheritance has its merits, but composition works too, and you can probably do with it anything you would do with inheritance.

If your migration is simple enough I would suggest to re-model according to the Orchard conversions.

If you must keep the existing inheritance structure than it should be possible to map the structure using PersistenceConfiguration and JoinedSubclassConvention .
Here is an example.
Beware: do not go this way if you can do with composition!
The example utilizes some code that is in a pull request (ISessionConfigurationEventsWithParameters).
This was tested some time ago. It may be broken and may need some more work, but it should give useful direction.
     public class IbnJoinedSubclassConvention : IJoinedSubclassConvention
    {
        private readonly Dictionary<Type, RecordBlueprint> _descriptors;

        public IbnJoinedSubclassConvention(Dictionary<Type, RecordBlueprint> descriptors)
        {
            _descriptors = descriptors;
        }

        public void Apply(IJoinedSubclassInstance instance)
        {
            if (instance.EntityType.FullName.StartsWith("Ibn")) {
                instance.Key.Column("Id");
                RecordBlueprint desc;
                if (_descriptors.TryGetValue(instance.EntityType, out desc)) {
                    instance.Table(desc.TableName);
                }
            }
        }
    }

    public class PersistenceConfiguration : ISessionConfigurationEventsWithParameters
    {
        public Orchard.Data.Providers.SessionFactoryParameters Parameters { get; set; }

        public PersistenceConfiguration()
        {
        }

        public void Created(FluentConfiguration cfg, AutoPersistenceModel defaultModel)
        {
           Dictionary<Type, RecordBlueprint> descriptors = Parameters.RecordDescriptors.ToDictionary(d => d.Type);
           defaultModel.Conventions.Add(new IbnJoinedSubclassConvention(descriptors));
        }
... some irrelevant interface methods ...

}