I'm converting a previous project from using normal NHibernate hbm.xml mappings to Fluent NHibernate. Currently, I'm stuck on what should be one of the last steps to getting this working. I've added a derived class for DefaultAutomappingConfiguration to modify my ID naming convention. The string "Id" is appended to the class name:
public override bool IsId(FluentNHibernate.Member member)
{
return member.Name == member.DeclaringType.Name + "Id";
}
This should make "Agency" have an ID in a field named "AgencyId". Instead, I'm getting this error:
The entity 'ClassMap`1' doesn't have an Id mapped. Use the Id method to map your identity property. For example: Id(x => x.Id).
{Name = "ClassMap`1" FullName = "FluentNHibernate.Mapping.ClassMap`1[[BackendDb.Model.Agency, BackendDb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}
I made a breakpoint on the IsId function to see what's going on:
{Property: Cache}
{Name = "ClassMap`1" FullName = "FluentNHibernate.Mapping.ClassMap`1[[BackendDb.Model.Agency, BackendDb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}
What is this? The object is not something I've created. Every other object passes through this function fine, and the ones I actually wanted to map are returning the proper value.
My Session factory looks something like this:
var cfg = new MapConfig();
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(m => m.Server(@".\SqlExpress")
.Database("{some dbname}")
.TrustedConnection()))
.Mappings(m =>
m.AutoMappings
.Add(AutoMap.AssemblyOf<Agency>(cfg))
)
.BuildSessionFactory();
Annoyingly, it seems that this somehow caused the three tables I was testing Fluent NHibernate on in my dev database to be emptied. What the hell?
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:
And in my
DefaultAutomappingConfiguration
override class: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.
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 anAgencyMap
in the assembly andClassMap<>
does not have anId
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: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:
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):To handle the primary key mapping, I create a convention class:
Finally, I configure my SessionFactory to use the configuration/convention classes: