开发者

Automapping doesn't have an Id mapped

开发者 https://www.devze.com 2022-12-24 08:15 出处:网络
My Entity Class: public class Building { /// <summary> /// internal Id /// </summary> public virtual long Id { get; set; }
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.ValidationExceptio开发者_如何学Gon: The entity doesn't have an Id mapped. Use the Id method to map your identity property. For example: Id(x => x.Id)..


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


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

  1. Generated Property Name = Same as database column name (No change)
  2. Mapping Style = Fluent Mapping
  3. Field or Property = Auto Property

Languages available: C# and VB

  1. Folder : [your project folder]\Entities
  2. Namespace : [your project namespace].Entities
  3. Assembly Name: [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!


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号