我使用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; }
...
}