请求子类时如何阻止Automapper映射到父类 [英] How to stop Automapper from mapping to parent class when child class was requested

查看:195
本文介绍了请求子类时如何阻止Automapper映射到父类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力在我们的服务中实现AutoMapper,并且在单元测试中看到了一个非常令人困惑的问题.

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

它也涉及这些对象,尽管此时我还没有使用AutoMapper映射它们:

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; }
}

这些类使用包括以下内容的自定义代码进行转换,其中source是DbParty:

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);
} 

我遇到的测试创建了一个新的DbParty,两个与新的DbParty链接的新DbAccounts,以及两个与新的DbParty链接的2个新的DbPartyAccountRoles,以及每个与每个DbAccounts链接的1个. 然后,它通过DbParty存储库测试某些更新功能.如果需要,我可以为此添加一些代码,只需花费一些时间进行清理.

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.

单独运行时,此测试运行良好,但与另一个测试在同一会话中运行(我将在下面详细介绍)时,上述转换代码中的Mapper调用会抛出此异常:

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'.

另一个测试还创建了一个只有一个DbAccount的新DbParty,然后创建了3个DbPartyAccountRoles.我能够将测试范围缩小到可以打破其他测试的确切范围,它是:

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.

有了这些信息,我的猜测是测试失败了,原因是调用AutoMapper时与DbAccount对象后面的CastleProxy有关,但我对此一无所知.

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.

我现在设法运行了相关的功能测试(对服务本身进行了调用),并且它们似乎运行良好,这使我认为单元测试设置可能是一个因素,最值得注意的是所涉及的测试在内存数据库中针对SqlLite运行.

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.

推荐答案

该问题最终与在单元测试中多次运行AutoMapper Bootstrapper有关.调用是在我们的测试基类的TestFixtureSetup方法中进行的.

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.

这篇关于请求子类时如何阻止Automapper映射到父类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆