当请求子类时,如何阻止Automapper映射到父类

本文关键字:Automapper 映射 父类 何阻止 请求 子类 | 更新日期: 2023-09-27 18:12:14

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

首先,这个问题涉及到以下对象和它们各自的映射:

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:

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:

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, 2个链接到新DbParty的新DbAccounts,以及2个链接到新DbParty的新DbPartyAccountRoles,每个DbAccounts各1个。然后通过DbParty存储库测试一些更新功能。我可以包括一些代码,如果需要的话,它只是需要一些时间来清理。

单独运行时,这个测试工作得很好,但是当与另一个测试(我将在下面详细说明)在同一会话中运行时,上述转换代码中的Mapper调用会抛出这个异常:

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

另一个测试也创建了一个新的DbParty,但是只有一个DbAccount,然后创建了3个DbPartyAccountRoles。我能够将这个测试缩小到与另一个测试断开的确切行,它是:

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

注释掉这一行允许其他测试通过。

有了这些信息,我的猜测是测试正在中断,因为在调用AutoMapper时,与DbAccount对象背后的CastleProxy有关,但我不知道如何。

我现在已经设法运行了相关的功能测试(对服务本身进行调用),它们似乎工作得很好,这使我认为单元测试设置可能是一个因素,最值得注意的是,所讨论的测试是针对内存数据库中的sqlite运行的。

当请求子类时,如何阻止Automapper映射到父类

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

修复方法是在创建映射之前添加以下行:
Mapper.Reset();

我仍然很好奇为什么这是唯一一个有问题的地图