How to stop Automapper from mapping to parent class when child class was requested

这一生的挚爱 提交于 2019-12-23 08:52:32

问题


I am working on implementing AutoMapper in our service and am seeing a very confusing issue in our unit tests.

First off this issue involves the following objects and their respective maps:

public class DbAccount : ActiveRecordBase<DbAccount>
{
    // this is the ORM entity
}

public class Account
{
    // this is the primary full valued Dto
}

public class LazyAccount : Account
{
    // this class as it is named doesn't load the majority of the properties of account
}

Mapper.CreateMap<DbAccount,Account>(); 
//There are lots of custom mappings, but I don't believe they are relevant

Mapper.CreateMap<DbAccount,LazyAccount>(); 
//All non matched properties are ignored

It also involves these objects, though I haven't mapped these with AutoMapper at this point:

public class DbParty : ActiveRecordBase<DbParty>
{
    public IList<DbPartyAccountRole> PartyAccountRoles { get; set; }
    public IList<DbAccount> Accounts {get; set;}
}

public class DbPartyAccountRole : ActiveRecordBase<DbPartyAccountRole>
{
    public DbParty Party { get; set; }
    public DbAccount Account { get; set; }
}

These classes are converted using custom code that includes the following, where source is a DbParty:

var party = new Party()
//field to field mapping here

foreach (var partyAccountRole in source.PartyAccountRoles)
{
    var account = Mapper.Map<LazyAccount>(partyAccountRole.Account);
    account.Party = party;
    party.Accounts.Add(account);
} 

The test I'm having an issue with creates a new DbParty, 2 new DbAccounts linked to the new DbParty, and 2 new DbPartyAccountRoles both linked to the new DbParty and 1 each to each of the DbAccounts. It then tests some update functionality via the DbParty repository. I can include some code for this if needed it will just take some time to scrub.

When run by itself this test works just fine, but when run in the same session as another test (that I will detail below) the Mapper call in the above conversion code throws this exception:

System.InvalidCastException : Unable to cast object of type '[Namespace].Account' to type '[Namespace].LazyAccount'.

The other test also creates a new DbParty but with only one DbAccount and then creates 3 DbPartyAccountRoles. I was able to narrow this test down to the exact line that breaks the other test and it is:

Assert.That(DbPartyAccountRole.FindAll().Count(), Is.EqualTo(3))

Commenting out this line allows the other test to pass.

With that information my guess is that the test is breaking because of something to do with the CastleProxy that is behind the DbAccount object when calling AutoMapper but I don't have the slightest idea of how.

I've now managed to run the relevant functional tests (making calls against the service itself) and they seem to work fine, this makes me think the unit test setup may be a factor, most notable is that the tests in question are run against a SqlLite in memory database.


回答1:


The problem ended up being related to running the AutoMapper Bootstrapper multiple times in the unit tests; the invocation was in the TestFixtureSetup method on our testing base class.

The fix was to add the following line before creating the maps:

Mapper.Reset();

I am still curious as to why this was the only map that had an issue.



来源:https://stackoverflow.com/questions/32489127/how-to-stop-automapper-from-mapping-to-parent-class-when-child-class-was-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!