Fluent NHibernate error: The entity 'ClassMap`1' doesn't have an Id mapped

一世执手 提交于 2019-12-05 14:25:34

The sessionfactory is trying to automap all classes in the assembly that contains your Agency class based on this directive: Add(AutoMap.AssemblyOf<Agency>(cfg)). Since you have an AgencyMap in the assembly andClassMap<> does not have an Id property, FNH is throwing an error.

If you want to use ClassMap<> configurations, instead of (or in addition to) declaring an automapping configuration, declare a fluent mapping:

m.FluentMappings.AddFromAssemblyOf<Agency>();

If you don't need AutoMappings, remove the `.AutoMappings.Add' directive.

However, if you want to use AutoMappings, you need to tell FNH what classes you want to map. To handle this, I usually define a marker interface:

public abstract class Entity : IPersistable
{
    public virtual int Id { get; set; }
}

public interface IPersistable
{
}

Then, in the class that I derive from DefaultAutomappingConfiguration, I tell FNH to only map the classes that have that interface (you can limit the mapped classes however you see fit):

public class EntityAutoMappingConfiguration : DefaultAutomappingConfiguration
{
    public override bool ShouldMap(Type type)
    {
        return type.GetInterfaces().Contains(typeof (IPersistable));
    }

}

To handle the primary key mapping, I create a convention class:

public class PrimaryKeyNamePlusId : IIdConvention 
{
    public void Apply(IIdentityInstance instance)
    {
        instance.Column(instance.EntityType.Name+"Id");
    }
}

Finally, I configure my SessionFactory to use the configuration/convention classes:

 m.AutoMappings.AssemblyOf<Entity>(new EntityAutoMappingConfiguration())
            .IgnoreBase<Entity>()
            .UseOverridesFromAssemblyOf<Entity>()
            .Conventions.AddFromAssemblyOf<Entity>();

You can't use ClassMap in combination with the automapper unless you also configure the automapper to ignore the Entites for which you are using ClassMap and their respective mapping files.

In my case, I happen to use a custom attribute to indicate classes which should be automapped, so I can toss all sorts of garbage I don't want mapped into my .dll without having Fluent try to automap it:

/// <summary>
/// Add this attribute to entity classes which should be automapped by Fluent.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
class AutomapAttribute : Attribute
{
}

And in my DefaultAutomappingConfiguration override class:

    public override bool ShouldMap(Type type)
    {
        return (type.Namespace == "Data.Entities" 
            && type.GetCustomAttributes(typeof(AutomapAttribute), false).Length > 0);
    }

Of course, you don't need to check for an attribute if you just keep your automapped entities in a different namespace from other classes.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!