Reputation: 96
My Entity Class:
public class Building
{
/// <summary>
/// internal Id
/// </summary>
public virtual long Id { get; set; }
..............
}
My Mapping:
var model = AutoMap.AssemblyOf<Building>()
.Setup(s => s.FindIdentity = p => p.Name == "Id")
.Where(t => t.Namespace == "SpikeAutoMappings");
var database = Fluently.Configure()
.Database(DatabaseConfigurer)
.Mappings(m=>m.AutoMappings.Add(model));
I need somebody to help me see what is wrong because I keep having this error when run unit test:
Initialization method TestProject1.MappingTestBase.TestInitialize threw exception. FluentNHibernate.Cfg.FluentConfigurationException: FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
---> FluentNHibernate.Visitors.ValidationException: The entity doesn't have an Id mapped. Use the Id method to map your identity property. For example: Id(x => x.Id)..
Upvotes: 3
Views: 9130
Reputation: 21
Generally, using AutoMapping
is a poor policy because the filed Id
must exist in your database tables. Instead, consider using a fluent mapping generator, such as NMG to handle your mapping.
In this case, you would first want to download/install the application, then generate the Mapping Files from your database (Oracle, SQL and various others).
In order to create the Mapping Files, first create an /Entities/
folder within your project. Next, configure the generator software as follows:
Preferences
Languages available: C# and VB
[your project folder]\Entities
[your project namespace].Entities
[your project name].Entities
Next, either Generate All or Generate the Specific Table.
All of the *.cs
and *Map.cs
files should now be created in your project (you can add them with Add Existing Item...
if they don't show up).
Using Fluent, you will see something like the following:
Id(x => x.keyName_ID)
.Column(x => x.keyname_ID)
.GeneratedBy
.Sequence("keyname_ID")
or
Id(x => x.keyName_ID)
.Column(x => x.keyname_ID)
.GeneratedBy
.Identity()
.Column("keyname_ID")
or
Id(x => x.keyName_ID)
.Column(x => x.keyname_ID)
.GeneratedBy
.Assigned()
So, now we need to specify the Id
using FluentMapping
with Fluent nHibernate
. To do this, you need to overwrite the Id
line of on code in each of the Map
files in the solution. Simply add:
Id(x => x.KeyName_ID)
.GeneratedBy
.GetGeneratorMapping()
.IsSpecified("KeyName_ID");
Where keyname_id
is the column name of the id
in your database, rather than the one created.
Notice that in your mapping at the BuildSession
you must have:
(...).Mappings(m =>
m.FluentMappings.AddFromAssemblyOf<[one of your entities]>()
);
And, now Id
is mapped. :) I hope this helps!
Upvotes: 2
Reputation: 6742
both answers above are right; unless you specify differently, the automapper assumes that you have an int Id field.
If your Id is long, the automapper might not recognize it correctly.
try defining a MappingOverride for your class(es), like so:
public class UserMappingOverride : IAutoMappingOverride<User>
{
#region IAutoMappingOverride<User> Members
public void Override(AutoMapping<User> mapping)
{
mapping.Id(u => u.Name);
}
#endregion
}
the Id() function allows you to override the automapper's convention of what the ID field should be.
for further info on overriding, see http://wiki.fluentnhibernate.org/Auto_mapping#Overrides.
Cheers,
Jhonny
Upvotes: 9
Reputation: 5875
My experience with Automapping is that as long as your Entity class has the line:
public virtual int Id { get; private set; }
the automapper will treat it as an ID with no further help from the programmer (i.e. no need for the FindIdenity code you are using in your AutoMap call).
The only difference I see in your ID declaration is that you use a type long instead of int. Don't know if this matters or not.
Upvotes: 0