我有以下情况
实体框架类类:
public class Block
{
public Guid Id { get; set; }
public ICollection<BlockLocation> BlockLocations { get; set; }
public BlockType Type { get; set; }
}
public class BlockLocation
{
public Guid Id { get; set; }
public Guid BlockId { get; set; }
public Block Block { get; set; }
}
我的域实体看起来像
public class Block
{
public Block(BlockType type = BlockType.None) : this()
{
Type = type;
}
private Block() { }
public Guid Id { get; set; }
public List<BlockLocation> BlockLocations { get; set; }
public BlockType Type { get; set; }
}
public class LiveBlock : Block
{
public LiveBlock() : base(BlockType.Live) { }
}
public class UnsequencedBlock : Block
{
public UnsequencedBlock() : base(BlockType.Unsequenced) { }
}
public class BlockLocation
{
public Guid Id { get; set; }
public Guid BlockId { get; set; }
public Block Block { get; set; }
}
public enum BlockType
{
None = 0,
Live,
Unsequenced
}
我想做的是从Entity Framework映射到Domain实体到子类型,并保留引用,以免堆栈溢出
我的映射是
cfg.CreateMap<Data.Block, Domain.LiveBlock>();
cfg.CreateMap<Data.Block, Domain.UnsequencedBlock>();
cfg.CreateMap<Data.Block, Domain.Block>().PreserveReferences().ConstructUsing((block, context) =>
{
if (block.Type == BlockType.Live)
{
// This loops until stack overflow
return context.Mapper.Map<Domain.LiveBlock>(block);
}
if (block.Type == BlockType.Unsequenced)
{
return context.Mapper.Map<Domain.LiveBlock>(block);
}
return context.Mapper.Map<Domain.Block>(block);
});
cfg.CreateMap<Data.BlockLocation, Domain.BlockLocation>();
我正在尝试执行以下操作:
// This is the EF entity
var block = new Data.Block
{
Id = Guid.NewGuid(),
Type = BlockType.Live,
BlockLocations = new List<Data.BlockLocation>
{
new BlockLocation {Id = Guid.NewGuid()},
new BlockLocation {Id = Guid.NewGuid()}
}
};
block.BlockLocations[0].Block = block;
block.BlockLocations[1].Block = block;
// Trying to create a Domain entity
var domainBlock = Mapper.Map<Data.Block, Domain.Block>(block);
我想要实现的结果是 domainBlock 的类型为LiveBlock,并具有BlockLocations列表,这些BlockLocations的LiveBlock实体与其 Block 属性相同
我得到的是ConstructUsing中的一个循环,直到出现堆栈溢出。
现在,我的问题是:
我知道一种解决方法是忽略 Domain.Block 中的 BlockLocations 属性,并分别映射它们,但我想为此使用Automapper自动。
谢谢您的帮助。
答案 0 :(得分:1)
在Lucian的帮助下使其正常工作
我将映射器更改为以下
cfg.CreateMap<Data.Block, Domain.LiveBlock>().PreserveReferences();
cfg.CreateMap<Data.Block, Domain.UnsequencedBlock>().PreserveReferences();
cfg.CreateMap<Data.Block, Domain.Block>().PreserveReferences().ConstructUsing((block, context) =>
{
if (block.Type == BlockType.Live)
{
var b = new LiveBlock();
return context.Mapper.Map(block, b, context);
}
if (block.Type == BlockType.Unsequenced)
{
var unsequencedBlock = new UnsequencedBlock();
return context.Mapper.Map(block, unsequencedBlock, context);
}
return context.Mapper.Map<Domain.Block>(block);
});
cfg.CreateMap<Data.BlockLocation, Domain.BlockLocation>().PreserveReferences();
secred是使用以上下文为参数的Map方法
context.Mapper.Map(block, unsequencedBlock, context);