2010-01-27 12 views
5

Başlığın mantıklı olup olmadığından emin değilim, ama işte yaptığım şey bu. Varlık Çerçeve Varlıklarımı DTO nesnelerine eşlemek için AutoMapper kullanıyorum veya tam tersi. Sorun DTO verilerini EF nesnesine eşlemeye çalıştığımda ortaya çıkıyor. EntityKey için mülk haritalama özelliği yok. Bunu düzeltmek için, aşağıdaki gibi bazı yapın: Ben 1 sınıf var olabilir bunu yapmanın daha genel bir yolu olup olmadığını merak ediyorumEF Entities için EntityKey değerlerini eşlemek için AutoMapper ValueResolver'ı kullanmanın genel bir yolu var mı?

public class VideoEntityKeyResolver : ValueResolver<VideoDTO, EntityKey> 
{ 
    protected override EntityKey ResolveCore(VideoDTO source) 
    { 
     EntityKey key = new EntityKey("EntityFrameworkTestingEntities.Videos", 
      "VideoId", source.VideoId); 
     return key; 
    } 
} 

: gibi

 Mapper.CreateMap<VideoDTO, Video>() 
      .ForMember(dest => dest.EntityKey, opt => 
opt.ResolveUsing<VideoEntityKeyResolver>()); 

VideoEntityKeyResolver sınıf görünüyor Varlık Kümesi Adını, Anahtar Mülk Adını ve Anahtar Değerini bir yapıcıya alan bir kurucu ile.

DTO nesnelerinin oluşturulmasının tüm noktası olarak veri katmanımın bağlantısını uygulamamın geri kalanında ciddi bir şekilde çekmek için akışları geçmeye çok benzeyen DTO nesnelerime bir EntityKey özelliği eklemeyi düşündüm. .

Tamamen ilgisiz bir notta (gerekirse yeni bir soru oluşturabilirim), AutoMapper kullanırken eşlemlerimi tanımlamam gereken tam olarak nedir? Şu anda onu bağlam nesnesinin kurucusunda yapıyorum (bu benim EF deposu nesnemdir), ancak bunun oldukça maliyetli ve doğru değil, yine de işe yaradığını düşünüyorum.

cevap

8

Ben şimdiye kadar bu test etmek olarak gitmedik ama şu çalışmalıdır:

public class EntityKeyResolver<T, TProperty> : ValueResolver<T, EntityKey> where T : class 
{ 
    private Expression<Func<T, TProperty>> _propertyExpression; 
    private string _qualifiedEntitySetName; 
    private string _keyName; 

    public EntityKeyResolver(string qualifiedEntitySetName, string keyName, Expression<Func<T, TProperty>> propertyExpression) 
    { 
     _qualifiedEntitySetName = qualifiedEntitySetName; 
     _keyName = keyName; 
     _propertyExpression = propertyExpression; 
    } 

    protected override EntityKey ResolveCore(T source) 
    { 
     return new EntityKey(_qualifiedEntitySetName, _keyName, ExpressionHelper.GetValue(_propertyExpression)); 
    } 
} 

ExpressionHelper Ben vakaların çeşitli ifadeleri değerlendirmek için kullandıkları statik sınıftır. GetValue yöntemi şöyle görünür:

internal static TProperty GetValue<T, TProperty>(T obj, Expression<Func<T, TProperty>> expression) where T : class 
{ 
    if (obj == null) 
    { 
     return default(TProperty); 
    } 

    Func<T, TProperty> func = expression.Compile(); 

    return func(obj); 
} 

şöyle Daha sonra kod değiştirecek (varsayarak VideoId bir Guıd olan): İstediğin daha

Mapper.CreateMap<VideoDTO, Video>()   
      .ForMember(dest => dest.EntityKey, opt => opt.ResolveUsing(new EntityKeyResolver<VideoDTO, Guid>("EntityFrameworkTestingEntities.Videos", "VideoId", v => v.VideoId))); 

Muhtemelen biraz daha ayrıntılı. Jenerik resolvere alternatif (onlar hakkında aynı derecede ayrıntılı olan) varlık anahtar eşleştirmek MapFrom kullanmak olacaktır: Diğer sorunuza gelince

Mapper.CreateMap<VideoDTO, Video>()   
       .ForMember(dest => dest.EntityKey, opt => opt.MapFrom(src => new EntityKey("EntityFrameworkTestingEntities.Videos", "VideoId", src.VideoId))); 

, bir statik sınıf oluşturarak alışkanlığı attığınıza Haritalarımı ilklendirir ve eşlemelerin oluşturulup oluşturulmadığına dair bir Boolean oluşturur. Daha sonra, depomun kurucusunda, sadece MapInitializer.EnsureMaps();

+0

'u arayın. Ayrıntılı yanıt için teşekkürler. Çoğu benim kafamın üzerinde, ama senden daha çok. Hala lambda'nın kullanımıyla güreşiyorum. Her nasılsa, bir mülke hesaplanmış bir değeri açıkça atamanıza izin veren bir otomatik haritalama yöntemi olup olmadığını biliyor musunuz? Bu durumda, gerekli parametrelere sahip bir EntityKey nesnesi oluşturabilir ve bu değeri varlığımdaki EntityKey özelliğine eşleyebilirim. MapMrom AutoMapper yöntemine bakmıştım, ama içine girmek için zamanım olmadı. – jason

+0

Bunu daha basit bir yöntem olarak önereceğim, ancak sorunuzu doğrudan yanıtlamaya karar verdim. Bunu cevaba ekleyeceğim. (Ayrıca, ihtiyaçlarınızı karşılamak için bulursanız, cevap vermeyi ve/veya cevabı kabul etmeyi unutmayın) – mkedobbs

+0

Bu soruya yukarıdan ve ötesine geçtiğiniz için teşekkür ederiz. Bu gerçekten bana yardımcı oldu! Devam ettim ve bir EntityKey mülküne eşleme yapmaya karar verdim ve işe yaramış gibi görünüyor. – jason

İlgili konular