尝试在单元测试中使用映射器配置文件时出现此错误
错误:
System.InvalidOperationException: 'Coalesce used with type that cannot be null'
堆栈跟踪:
at System.Linq.Expressions.Expression.ValidateCoalesceArgTypes(Type left, Type right)
at System.Linq.Expressions.Expression.Coalesce(Expression left, Expression right, LambdaExpression conversion)
at System.Linq.Expressions.Expression.Coalesce(Expression left, Expression right)
at AutoMapper.Execution.TypeMapPlanBuilder.CheckReferencesCache(Expression valueBuilder)
at AutoMapper.Execution.TypeMapPlanBuilder.ConstructorMapping(ConstructorMap constructorMap)
at AutoMapper.Execution.TypeMapPlanBuilder.CreateNewDestinationFunc()
at AutoMapper.Execution.TypeMapPlanBuilder.CreateDestinationFunc()
at AutoMapper.Execution.TypeMapPlanBuilder.CreateMapperLambda()
at AutoMapper.TypeMap.CreateMapperLambda(IGlobalConfiguration configuration)
at AutoMapper.TypeMap.Seal(IGlobalConfiguration configuration)
at AutoMapper.MapperConfiguration.<.ctor>g__Seal|20_0()
at AutoMapper.MapperConfiguration..ctor(MapperConfigurationExpression configurationExpression)
at AutoMapper.MapperConfiguration..ctor(Action`1 configure)
如何复制:
using AutoMapper;
namespace UnitTestIssue
{
public class TreeEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
public InternalNodeEntity InternalNode { get; set; }
public bool IsDeleted { get; set; }
}
public class InternalNodeEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
public List<InternalNodeEntity> InternalNodes { get; set; }
public List<LeafNodeEntity> LeafNodes { get; set; }
public bool IsDeleted { get; set; }
}
public class LeafNodeEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
public bool IsDeleted { get; set; }
}
public record struct TreeDto(Guid Id, string Name, InternalNodeDto Nodes, bool IsDeleted);
public record struct InternalNodeDto(Guid Id, string Name, List<InternalNodeDto> InternalNodes, List<LeafNodeDto> LeafNodes, bool IsDeleted);
public record struct LeafNodeDto(Guid Id, string Name, bool IsDeleted);
public class Tests
{
private IMapper _mapper;
[SetUp]
public void Setup()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<LeafNodeDto, LeafNodeEntity>().ReverseMap();
cfg.CreateMap<InternalNodeDto, InternalNodeEntity>().ReverseMap();
cfg.CreateMap<TreeDto, TreeEntity>().ReverseMap();
});
config.AssertConfigurationIsValid();
_mapper = config.CreateMapper();
}
[Test]
public void Test1()
{
//doesn't matter, just to invoke [Setup]
Assert.That(1, Is.EqualTo(1));
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="12.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="NodaTime" Version="3.1.9" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
<PackageReference Include="NUnit.Analyzers" Version="3.6.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.2.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
我尝试将可为空的 sytanx 与 Guid、字符串、InternalNode、LeafNode 一起使用,但似乎我无法破解它。
另外我觉得 Coalesce 在 List
这是一个非常简单的项目,可以向一些学生传授 WebAPI 模式的基础知识,即
Api Controller Action --> Service (map dto -> entity) --> repository --> context (save/retireve to/from DB)
几乎可以肯定错误是因为您的顶级 DTO 需要是引用类型,而不是值类型。从您的
struct
中删除
record struct
关键字
Automapper 似乎不支持记录结构映射,[mre] 将是:
record struct T1(int i);
record struct T2(int i);
[Test]
public void Test2()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<T1, T2>();
});
config.AssertConfigurationIsValid();
}
您可以将所有内容更改为简单记录,然后以下内容将起作用:
[Test]
public void Test2()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<LeafNodeDto, LeafNodeEntity>().ReverseMap();
cfg.CreateMap<InternalNodeDto, InternalNodeEntity>().ReverseMap();
cfg.CreateMap<TreeDto, TreeEntity>()
.ForMember(entity => entity.InternalNode, expression => expression.MapFrom(dto => dto.Nodes))
.ReverseMap();
});
config.AssertConfigurationIsValid();
}