2010-03-29 7 views
2

J'essaie de mapper int IdPost sur DTO pour Poster un objet sur un objet Blog, en fonction d'une règle.AutoMapper map IdPost to Post

je voudrais y parvenir: BlogDTO.IdPost => Blog.Post

poste serait chargé par NHibernate: Session.load (IdPost)

Comment puis-je obtenir cela avec AutoMapper?

+0

ans vous devez ajouter la balise NHibernate – Buthrakaur

+1

vous pouvez le faire facilement avec le ValueInjecter http://valueinjecter.codeplex.com/documentation – Omu

Répondre

0

Vous pouvez définir l'action AfterMap pour charger des entités à l'aide de NHibernate dans votre définition de mappage. J'utilise quelque chose comme ça pour but simmilar:

 mapperConfiguration.CreateMap<DealerDTO, Model.Entities.Dealer.Dealer>() 
      .AfterMap((src, dst) => 
       { 
        if (src.DepartmentId > 0) 
         dst.Department = nhContext.CurrentSession.Load<CompanyDepartment>(src.DepartmentId); 
        if (src.RankId > 0) 
         dst.Rank = nhContext.CurrentSession.Load<DealerRank>(src.RankId); 
        if (src.RegionId > 0) 
         dst.Region = nhContext.CurrentSession.Load<Region>(src.RegionId); 
       }); 
+0

c'est très laborieux. Vous devez faire en sorte que le cadre fasse tout le travail pour vous. – epitka

0
  1. Créer une nouvelle Id2EntityConverter

    public class Id2EntityConverter<TEntity> : ITypeConverter<int, TEntity> where TEntity : EntityBase 
    { 
        public Id2EntityConverter() 
        { 
         Repository = ObjectFactory.GetInstance<Repository<TEntity>>(); 
        } 
    
        private IRepository<TEntity> Repository { get; set; } 
    
        public TEntity ConvertToEntity(int id) 
        { 
         var toReturn = Repository.Get(id); 
         return toReturn; 
        } 
    
        #region Implementation of ITypeConverter<int,TEntity> 
    
        public TEntity Convert(ResolutionContext context) 
        { 
         return ConvertToEntity((int)context.SourceValue); 
        } 
    
        #endregion 
    } 
    
  2. Configurer AM créer automatiquement des cartes pour chaque type

    public class AutoMapperGlobalConfiguration : IGlobalConfiguration 
    { 
        private AutoMapper.IConfiguration _configuration; 
    
        public AutoMapperGlobalConfiguration(IConfiguration configuration) 
        { 
         _configuration = configuration; 
        } 
    
        public void Configure() 
        { 
         //add all defined profiles 
         var query = this.GetType().Assembly.GetExportedTypes() 
          .Where(x => x.CanBeCastTo(typeof(AutoMapper.Profile))); 
    
         _configuration.RecognizePostfixes("Id"); 
    
         foreach (Type type in query) 
         { 
          _configuration.AddProfile(ObjectFactory.GetInstance(type).As<Profile>()); 
         } 
    
         //create maps for all Id2Entity converters 
         MapAllEntities(_configuration); 
    
         Mapper.AssertConfigurationIsValid(); 
        } 
    
        private static void MapAllEntities(IProfileExpression configuration) 
        { 
         //get all types from the my assembly and create maps that 
         //convert int -> instance of the type using Id2EntityConverter 
         var openType = typeof(Id2EntityConverter<>); 
         var idType = typeof(int); 
         var persistentEntties = typeof(MYTYPE_FROM_MY_ASSEMBLY).Assembly.GetTypes() 
          .Where(t => typeof(EntityBase).IsAssignableFrom(t)) 
          .Select(t => new 
          { 
           EntityType = t, 
           ConverterType = openType.MakeGenericType(t) 
          }); 
         foreach (var e in persistentEntties) 
         { 
          var map = configuration.CreateMap(idType, e.EntityType); 
          map.ConvertUsing(e.ConverterType); 
         } 
        } 
    } 
    

Faites attention à la méthode MapAllEntities . Celui-ci va scanner tous les types et créer des cartes à la volée d'un entier à n'importe quel type d'EntityBase (qui dans notre cas est un type persistant). RecognizePostfix ("Id") dans votre cas pourrait être remplacer par RecognizePrefix ("Id")

+0

si vous avez besoin je peux vous envoyer toutes les pièces dont vous avez besoin pour configurer ceci par email – epitka

0

vous pouvez le faire facilement avec le ValueInjecter

ce serait quelque chose comme ceci:

//first you need to create a ValueInjection for your scenario 
     public class IntToPost : LoopValueInjection<int, Post> 
     { 
      protected override Post SetValue(int sourcePropertyValue) 
      { 
       return Session.Load(sourcePropertyValue); 
      } 
     } 

// and use it like this 
post.InjectFrom(new IntToPost().SourcePrefix("Id"), postDto); 

même si vous avez toujours le préfixe Id que vous pouvez définir dans le constructeur de la IntToPost et l'utiliser comme ceci:

post.InjectFrom<IntToPost>(postDto);