fluent nhibernate configuration not working

2019-09-13 01:32发布

问题:

Solved: ClassMap when configuration in code, ClassMapping when configuration in config file, but mapping in code.

When trying to save an object of type Object1 to my database I get the error:

No persister for: Object1.

Class definition:

public class Object1
{
    public virtual Guid Id { get; protected set; }
    public virtual DateTime Created { get; protected set; }
    public virtual DateTime LastModified { get; protected set; }
    public virtual Other Reference { get; set; }
}

mapping:

public class Object1Mapping : ClassMapping<Object1>
{
    public Object1Mapping()
    {
        Id(p => p.Id);
        Property(p => p.Created);
        Property(p => p.LastModified);
        ManyToOne(p => p.Reference, m => m.Cascade(Cascade.Remove));
    }
}

Configuration code:

sessionFactory = Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2012
        .ConnectionString(c => c
            .Server("serverUrl")
            .Database("myMsSqlDatabase")
            .Username("sa")
            .Password("pasword1")))
    .Mappings(m => m.FluentMappings
        .AddFromAssemblyOf<Object1Mapping>()
        .AddFromAssemblyOf<Object1>()
   .BuildSessionFactory();

All my classes are public and I added an AddFromAssemblyOf for every class that needs a persister. Also I tried both adding the classes themselves and the mapping classes. I know that one AddFromAssembly should be enough as should add all mapping classes from that assembly and all my mapping classes are in one project in one folder.

I managed to run diagnostics and it's looking through the correct Assembly, but it discovered no mappings, here is the result:

Fluent Mappings

Sources scanned:

Project.DomainModel.NHibernate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

Mappings discovered:

None found

Conventions

Sources scanned:

None found

Automapping

Skipped types:

None found

Candidate types:

None found

I've read tons of documentation and questions, it seems I'm missing something really obvious :(

回答1:

All different mapping types (by code, fluent, automapping, xml...) are supported by Fluently.Configure. It just needs different kind of code snippet to add it to your configuration.

Here are some different ways to add mappings to your configuration via Fluently configuration

.Mappings(m =>
{
    foreach (var assembly in MapAssemblies)
    {
        m.FluentMappings.AddFromAssembly(assembly);
        m.HbmMappings.AddFromAssembly(assembly);
        m.AutoMappings.Add(..)
    }    
})

...

.ExposeConfiguration(cfg => {
    foreach (var assembly in MapAssemblies)
    {
        cfg.AddDeserializedMapping(HbmMappingHelper.GetMappings(assembly), null);
        cfg.AddInputStream(NHibernate.Mapping.Attributes.HbmSerializer.Default.Serialize(
                    System.Reflection.Assembly.GetExecutingAssembly()));
    }

The above used helper class:

public class HbmMappingHelper
{
    public static HbmMapping GetMappings(Type[] types)
    {
        ModelMapper mapper = new ModelMapper();

        foreach (var type in types)
        {
            mapper.AddMappings(Assembly.GetAssembly(type).GetExportedTypes());
        }

        return mapper.CompileMappingForAllExplicitlyAddedEntities();
    }

    public static HbmMapping GetMappings(Assembly assembly)
    {
        ModelMapper mapper = new ModelMapper();

        mapper.AddMappings(assembly.GetExportedTypes());

        return mapper.CompileMappingForAllExplicitlyAddedEntities();
    }
}


回答2:

I think except to add all the mapping by foreach, you can do this.

 .Mappings(m =>m.FluentMappings
                   .AddFromAssemblyOf<Your_Class_For_Fluent_Configuration>()


回答3:

It seems that to use mappings in FluentNHibernate you need different mappings than are used when configuring NHibernate from a config file. ClassMapping originates from NHibernate.Mapping.ByCode.Conformist and ClassMap (found in code examples) originates from FluentNHibernate.Mapping

Tested this and it solves this problem, so changing the inheriting class from ClassMapping to ClassMap allowed the fluent configuration to find my mapping.