Skip to content

Id override is ignored if a property called 'Id' exists. #299

Open
@alex-davidson

Description

@alex-davidson

The following test fails:

[Test]
public void CanOverrideIdProperty()
{
    var model = AutoMap.Source(new StubTypeSource(new[] { typeof(EntityWithAlternateIdProperty) }))
        .Override<EntityWithAlternateIdProperty>(o =>
        {
            o.Id(e => e.AlternateId);
        });

    HibernateMapping hibernateMapping = model.BuildMappings().First();

    ClassMapping classMapping = hibernateMapping.Classes.First();
    ((IdMapping)classMapping.Id).Name.ShouldEqual("AlternateId");
}

public class EntityWithAlternateIdProperty
{
    public int Id { get; set; }
    public int AlternateId { get; set; }

    public string Name { get; set; }
}

It seems that AutoMapper#TryMapProperty considers only whether or not the property has already been seen, rather than considering the type of mappings being generated by the rule. The sequence of events seems to be something like:

  1. Override is applied, creating an IdMapping referring to AlternateId and applied at Layer.Defaults. AlternateId is marked as 'seen'.
  2. Begins applying defaults. Properties are iterated.
  3. The Id property is encountered. It has not yet been mapped, so the mapping steps are run against it.
  4. IdentityStep creates an IdMapping referring to Id and applies it at Layer.Defaults. This obliterates the IdMapping created by the override.

Adding o.Map(e => e.Id); to the override works around the problem because it prevents IdentityStep being executed for that property.

I would expect overrides to be applied at Layer.UserSupplied but this does not appear to be the case. Is this a bug, or intended behaviour?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions