Search code examples
c#fluent-nhibernatefluent-nhibernate-mapping

How do I setup Id of entity with a ConventionBuilder in Fluent NHibernate


I have following fluent configuration

var sessionFactory = Fluently.Configure()
                             .Database(configuration)
                             .Mappings(arg =>
                             {
                                 var autoMap = AutoMap.Source(typeSource);
                                 foreach (var convention in typeSource.GetConventions())
                                 {
                                     autoMap.Conventions.Add(convention);
                                 }
                                 autoMap.BuildMappings();
                             })
                             .BuildSessionFactory();

I use an instance (typeSource) of FluentNHibernate.ITypeSource that also has a method GetConventions, which returns System.Collections.Generic.IEnumerable<FluentNHibernate.Conventions.IConvention>.

The result of GetConventions is then used to be injected into Conventions of FluentNHibernate.Automapping.Automap (in the Mappings-method of the fluent configuration).

A concrete implementation of GetConventions looks like

public override System.Collections.Generic.IEnumerable<FluentNHibernate.Conventions.IConvention> GetConventions()
{
    yield return FluentNHibernate.Conventions.Helpers.ConventionBuilder.Property.When(
          arg => arg.Expect(f => f.Type == typeof (string)),
          arg => arg.CustomType<CUSTOMTYPE>()
    );
}

I would also like to introduce a convention to inject an ID based on the EntityType, which I've tried to do like:

yield return FluentNHibernate.Conventions.Helpers.ConventionBuilder.Class.When(
      arg => arg.Expect(f => f.EntityType == typeof (ENTITYTYPE)),
      arg => arg.Id // does not work, as .Id is readonly
);

So, how do I inject the ID, and possibly also a CombinedID, within a ConventionBuilder?

Edit:

I've also tried this, but sadly the breakpoint in the apply-path (var a = 1;) never gets reached:

yield return FluentNHibernate.Conventions.Helpers.ConventionBuilder.Id.When(
      arg => arg.Expect(f => f.EntityType == typeof(ENTITYTYPE)),
      arg =>
      {
          var a = 1;
      }
);

Solution

  • I solved this by extending the Mappings-call a bit:

    .Mappings(arg =>
    {
        var autoPersistenceModel = AutoMap.Source(typeSource);
        foreach (var overrideType in typeSource.GetOverrideTypes())
        {
            autoPersistenceModel.Override(overrideType);
        }
        foreach (var conventionType in typeSource.GetConventionTypes())
        {
            autoPersistenceModel.Conventions.Add(conventionType);
        }
        arg.AutoMappings.Add(autoPersistenceModel);
    })
    

    Unfortunately this is far from elegant or complete - it would be way more decent if AutoMap.Source(typeSource) could handle conventions and overrides from the GetTypes-method or if IIdConvention would be taken into account on building the maps (which it does not atm)...