我使用automapper从一个数据库导入到一个结构稍有不同的新数据库中。我不知道如何处理下面的代码表,如TargetType。 Automapper似乎在导入它们时会创建重复项(“无法确定'Models.ShipTarget_TargetType'关系的主体端,多个添加的实体可能具有相同的主键。”on db.SaveChanges())。我也遇到了与多对多关系相同的问题,但是我没有在那里发现错误,因为桥表允许AutoMapper在不违反任何限制的情况下快速创建重复项。如何在代码表上使用AutoMapper而不产生重复?
换句话说,当映射ShipTarget(有很多这些)时,当它映射TargetType字段(只有少数TargetTypes)时,它总是创建一个新的TargetType,而不是检查它是否已经存在于目标中并使用预先存在的实例。由于TargetType是一个代码表,因此我希望同一个实例可以在许多ShipTargets中共享一个特定的值。
请注意,在保存更改被调用之前,所有映射都在一次完成。所以目标数据库中绝对没有TargetTypes,所以我期望它会从源代码表中创建一个TargetType,但它会创建重复项,就像每个ShipTarget引用一个唯一的TargetType一样。
我当前的映射是这样的(简化,幸而没有错别字):
var src2NewShip = Mapper.CreateMap<SourceDataModel.Ship, Ship>()
.ForMember(newShp => newShp.Targets, c => c.MapFrom(srcShp => srcShp.ShipTargets));
var srcShipTargetType2NewTargetType = Mapper.CreateMap<SourceDataModel.ShipTargetType, TargetType>();
var srcShipTarget2SrcTarget = Mapper.CreateMap<SourceDataModel.ShipTarget, ShipTarget>()
.ForMember(newTarget => newTarget.TargetType, c => c.MapFrom(srcTarget => srcTarget.ShipTargetType));
我如何确保它只是作为有源数据库ShipTargetTypes,创建多TargetTypes?而不是在被多个ShipTarget引用时复制它们。
这个伪代码表示我有一个想法来解决问题,但是这似乎很令人费解,我不知道究竟是如何得到它的权利,无论如何努力:
var srcShipTarget2SrcTarget = Mapper.CreateMap<SourceDataModel.ShipTarget, ShipTarget>()
.ForMember(newTarget => newTarget.TargetType, c => c.MapFrom(srcTarget =>
{
newDb.Ships.SelectMany(s => s.ShipTargets).FirstOrDefault(st=>st.TargetType.UniqueName == srcTarget.UniqueName);
//here I would return the found instance, or call upon automapper to map srcTarget to a new TargetType and return that
//essentially, use existing, or return new
);
public class TargetType
{
[Key]
public int TargetTypeKey { get; set; }
public string UniqueName { get; set; }
...
}
public class ShipTarget
{
[Key]
public int ShipTargetKey { get; set; }
public int ShipKey { get; set; }
[ForeignKey("ShipKey")]
public Ship Ship { get; set; }
public int TargetTypeKey { get; set; }
[ForeignKey("TargetTypeKey")]
public TargetType TargetType { get; set; }
...
}
public class Ship
{
[Key]
public int ShipKey { get; set; }
public virtual ICollection<ShipTarget> Targets { get; set; }
...
}