2012-03-09 2 views
1

automapper를 사용하여 하나의 DB에서 약간 다른 구조의 새 DB로 가져옵니다. 아래의 TargetType과 같은 코드 테이블을 처리하는 방법을 잘 모르겠습니다. Automapper가 가져올 때 중복을 만드는 것 같습니다 (" 'Models.ShipTarget_TargetType'관계의 주요 끝을 확인할 수 없습니다. db.SaveChanges()에서 여러 개의 추가 된 엔터티에 동일한 기본 키가있을 수 있습니다.). 또한 많은 관계에서 동일한 문제가 있었지만 브리지 테이블을 사용하여 AutoMapper가 모든 제약 조건을 위반하지 않고 복제본을 행복하게 만들 수 있으므로 오류가 발생하지 않습니다.중복을 생성하지 않고 코드 테이블에서 AutoMapper를 사용하는 방법은 무엇입니까?

다른 말로하면, ShipTarget을 맵핑 할 때 TargetType 필드를 맵핑 할 때 (몇 개의 TargetTypes 만 있음), 대상에 이미 존재하는지 여부를 확인하는 대신 항상 새로운 TargetType을 작성합니다 기존 인스턴스를 사용합니다. TargetType은 코드 테이블이므로 많은 ShipTargets에서 공유되는 특정 값에 대해 동일한 인스턴스를 원합니다.

저장 변경 사항이 호출되기 전에 모든 매핑이 한 번에 완료됩니다. 따라서 대상 데이터베이스에는 TargetTypes가 전혀 존재하지 않으므로 소스 코드 테이블에서 각각 하나씩 만들 것을 기대하지만 각 ShipTarget이 고유 한 TargetType을 참조하는 것처럼 중복을 생성합니다. 나는 소스 DB에 ShipTargetTypes이 있기 때문에 그것은 단지 많은 TargetTypes를 생성되도록하려면 어떻게

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)); 

:

나의 현재의 매핑이 (간체, 잘하면 아무 오타)입니까? 하나 이상의 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; } 
    ... 
    } 

답변

0

내가 아래를하고 싶었다 코드 테이블이 참조 된 곳이면 어디든 적용 할 수 있도록 TargetType의 ConvertUsing에 있지만 기본 매핑을 사용하여 새로운 매핑을 생성하는 방법을 알 수 없었습니다. 아래에서 내가 어디 Mapper.Map(srcTarget.ShipTarget, newTarget.TargetType);

코드 테이블을 참조하는 클래스의 멤버 대신, 나는 처음에 무시하도록 말한다. 그 엔트리를 사용하여 새로운 코드 테이블에 엔트리가 존재 하는지를 검사하여 AfterMap에 매핑하고, 존재하지 않으면 새로운 엔트리를 생성하십시오.

var srcShipTarget2SrcTarget = Mapper.CreateMap<SourceDataModel.ShipTarget, ShipTarget>() 
    .ForMember(newTarget => newTarget.TargetType, c => c.Ignore()) 
    .AfterMap((srcTarget, newTarget) => 
    { 
     if (srcTarget.ProjectTargetType != null) 
     { 
     newTarget.TargetType = db.TargetTypes.FirstOrDefault(tt => tt.UniqueName == odsT.ProjectTargetType.UniqueName); 
     if (newTarget.TargetType == null) 
     { 
      newTarget.TargetType = Mapper.Map(srcTarget.ShipTarget, newTarget.TargetType); 
     } 
     } 
    }); 
관련 문제