0

Weird case with a legacy database: Most tables have the same named field for the primary key, but I have one table that has a different primary key but also has that named field. When I override the automap for this table it uses the convention not the override unless I explicitly override the mapping for the name field.

public class IdConvention : IIdConvention, IIdConventionAcceptance, 
{
    public void Accept(IAcceptanceCriteria<IIdentityInspector> criteria)
    {
        criteria.Expect(x => x.Type == typeof(string));
    }
    public void Apply(IIdentityInstance instance)
    {
        if (instance.Name == "StandardId")
            instance.Column("FooBarThingyId");
    }
}

public class WierdCase
{
  virtual int CustomId {get;set;}
  virtual int StandardId {get;set;}
}

public class WierdCaseOverride : IAutoMappingOverride<WierdCase>
{
    public void Override(AutoMapping<WierdCase> mapping)
    {
        mapping.Id(x => x.CustomId).GeneratedBy.Identity();
        mapping.Map(x => x.StandardId , "FooBarThingyId");
    }
}

public class CustomConfiguration : DefaultAutomappingConfiguration
{
     public override bool IsId(Member member)
    {
        if (member.DeclaringType.GetProperty("StandardId") != null)
            return member.Name == "StandardId";

        return base.IsId(member);
    }
 }

Without the mapping.Map() line, this uses StandardId as the key, not CustomId. I would expect calling mapping.Id() to override the convention, but it does not seem to.

What am I missing here? As I'd rather fix the convention than have to explicitly override it for the exceptions.

Malcolm
  • 1,239
  • 1
  • 14
  • 25
  • Have you overriden the Id property recognition of automapping? If not do it by overriding `DefaultAutomappingConfiguration.IsId()` to exclude `int StandardId` – Firo Jan 12 '16 at 12:56
  • That's what the IdConvention does. It's set in the config (which I didn't include). – Malcolm Jan 12 '16 at 23:30
  • IdConvention does not select the id property but configures it. You do not get all properties in the IdConvention.Apply method – Firo Jan 13 '16 at 07:40
  • See the code above - IIdConvention and IIdConventionAcceptance are both implemented. Is there something else needed? – Malcolm Jan 14 '16 at 02:22
  • yes: `DefaultAutomappingConfiguration.IsId()` as described in my first comment. The acceptance only filters from the picked Ids not from all properties. – Firo Jan 14 '16 at 11:09
  • Added the IsId() definition to the example code. – Malcolm Jan 14 '16 at 17:54
  • Your `IsId` always favors "StandardId" so CustomId will never be recognized as Id. Change it to `if (member.DeclaringType.GetProperty("CustomId") != null) return member.Name == "CustomId";` – Firo Jan 18 '16 at 11:16
  • That would then break all the mappings for StandardId, or require adding to the convention every time there was a non-standard Id (which defeats the point of having a convention and IAutoMappingOverride). The problem is that I don't want it to use StandardId if-and-only-if another key has already been defined. I can't find a way to do that. None of the configuration or convention interfaces seem to provide a way to see if a key has already been defined. I have several hundred tables with dozens of tables with exceptions, so I'm trying to find a general solution. – Malcolm Jan 18 '16 at 15:30
  • Are you sure that Automapping is the right choice then? You can manually map your classes with `ClassMap<>` and conventions for common things. It is easy to reuse mappings with base classes and helper functions. – Firo Jan 19 '16 at 09:19
  • Automapping is the right choice (if not for Ids, for all the other fields in these tables), I was just trying to avoid writing overrides for the Ids() for every single table. Like I said - hundreds of tables, the more we can automap the less work we have to do. (and altering the db to conform to a single convention unfortunately isn't an option). – Malcolm Jan 19 '16 at 17:39
  • i did map legacy dbs several times and it always depends on the what is there. All i want to say in my answer is that you need to get IsId right so that it gets the right id for all classes and then implement the IdConvention to configure the different kinds of ids. – Firo Jan 20 '16 at 08:59

0 Answers0