7

के साथ ऑटोमैपर और ईएफ 4 डीबीकॉन्टेक्स्ट का उपयोग करके व्यूमोडेल से मौजूदा इकाई को कैसे अपडेट करें I Entity और ViewModel ऑब्जेक्ट (दोनों दिशाओं में) के बीच मैप करने के लिए ऑटोमैपर का उपयोग कर रहा हूं। मॉडल ईएफ 4 डीबीकॉन्टेक्स्ट पीओसीओ का उपयोग करता है और LazyLoading (और इसलिए प्रॉक्सी जनरेशन) सक्षम है।आलसी लोडर सक्षम

मुझे व्यूमोडेल से मौजूदा इकाई को अपडेट करने का प्रयास करने में समस्या आ गई है। जब मैं Mapper.Map (vm, entity) को कॉल करता हूं, तो ऑटोमैपर अपवाद फेंकता है। मेरा सवाल है: ऑटोमैपर का उपयोग कर ईएफ प्रॉक्सी ऑब्जेक्ट्स के साथ आपको कैसे काम करना चाहिए?

कोड दिखता है (सरलीकृत) इस तरह:

'Mapper.Map(viewModel, resultSet)' threw an exception of type 'AutoMapper.AutoMapperMappingException' 
base {System.Exception}: {"Missing type map configuration or unsupported mapping.\n\nMapping types:\r\nResultSetView -> ResultSet_692D75838D4DC59B922F3E88CF1B10516CBF6CD8A32C4BE2F3FCC28CE83F0BD2\r\nSciensus.Applications.ClinicalStudies.Web.Areas.Patient.Models.ResultSetView -> System.Data.Entity.DynamicProxies.ResultSet_692D75838D4DC59B922F3E88CF1B10516CBF6CD8A32C4BE2F3FCC28CE83F0BD2\n\nDestination path:\nResultSet_692D75838D4DC59B922F3E88CF1B10516CBF6CD8A32C4BE2F3FCC28CE83F0BD2\n\nSource value:\nSciensus.Applications.ClinicalStudies.Web.Areas.Patient.Models.ResultSetView"} 
Context: {Trying to map ResultSetView to ResultSet_692D75838D4DC59B922F3E88CF1B10516CBF6CD8A32C4BE2F3FCC28CE83F0BD2.} 
Message: "Missing type map configuration or unsupported mapping.\n\nMapping types:\r\nResultSetView -> ResultSet_692D75838D4DC59B922F3E88CF1B10516CBF6CD8A32C4BE2F3FCC28CE83F0BD2\r\nSciensus.Applications.ClinicalStudies.Web.Areas.Patient.Models.ResultSetView -> System.Data.Entity.DynamicProxies.ResultSet_692D75838D4DC59B922F3E88CF1B10516CBF6CD8A32C4BE2F3FCC28CE83F0BD2\n\nDestination path:\nResultSet_692D75838D4DC59B922F3E88CF1B10516CBF6CD8A32C4BE2F3FCC28CE83F0BD2\n\nSource value:\nSciensus.Applications.ClinicalStudies.Web.Areas.Patient.Models.ResultSetView" 
StackTrace: "" 
+1

यह समस्या v2.2.1 –

उत्तर

6

मैं AutoMapper स्रोत कोड को देखा:

:
public TDestination Map<TSource, TDestination>(TSource source, TDestination destination) 
    { 
     return Map(source, destination, opts => { }); 
    } 

    public TDestination Map<TSource, TDestination>(TSource source, TDestination destination, Action<IMappingOperationOptions> opts) 
    { 
     Type modelType = typeof(TSource); 
     Type destinationType = (Equals(destination, default(TDestination)) ? typeof(TDestination) : destination.GetType()); 

     return (TDestination)Map(source, destination, modelType, destinationType, opts); 
    } 

समस्याएं इस जगह में हुई 210

Type destinationType = (Equals(destination, default(TDestination)) ? typeof(TDestination) : destination.GetType()); 

तो परिवर्तन है कि एक समस्या नहीं है:

Mapper.Map(vm, entity,typeof(ViewModel),typeof(MyEntity)); 
+0

धन्यवाद, यह काम करता है। इस प्रश्न का चिह्नित उत्तर वास्तव में एक उत्तर नहीं है क्योंकि यह कहता है, इसे मैन्युअल रूप से करने के लिए वापस जाएं। यह जवाब मेरी राय में प्रश्न का उत्तर होना चाहिए था। सवाल यह था कि ऑटोमैपर का उपयोग करके ईएफ प्रॉक्सी ऑब्जेक्ट को कैसे अपडेट किया जाए। –

+0

मैं एक ही मुद्दे पर टक्कर लगी। उल्लिखित समाधान ऑटोमैपर संस्करण 2.0.0.0 के साथ काम करेगा, और ऊपर नहीं। देखें: http://www.nopcommerce.com/boards/t/19897/urgent-issue-with-admin-mapping.aspx –

+1

ऑटोमैपर 2.2 के साथ, मुझे "टाइप 'ऑब्जेक्ट' को '' में पूर्ण रूप से परिवर्तित नहीं किया जा सकता है यह काम-आसपास है। शायद @YoYo में एक ही समस्या है, लेकिन इसका स्पष्ट रूप से उल्लेख नहीं किया गया है। –

3

:

public class MyEntity 
{ 
    public int Id {get;set;} 
    public int Name {get;set;} 
} 

public class ViewModel 
{ 
    public int Id {get;set;} 
    public int Name {get;set;} 
} 

Mapper.CreateMap<MyEntity, ViewModel>(); 
Mapper.CreateMap<ViewModel, MyEntity>(); 

public ActionResult Edit(ViewModel vm) 
{ 
    MyEntity entity = db.MyEntities.Find(vm.Id); 
    Mapper.Map(vm, entity); 
    db.Entry(entity).State = EntityState.Modified; 
    db.SaveChanges(); 
} 

जब मैं Mapper.Map (VM, इकाई) मौजूदा इकाई वस्तु अद्यतन करने के लिए कहते हैं, मैं अपवाद जैसा कि आपको संदेह है, मुझे विश्वास है कि आपको यह अपवाद मिल रहा है, क्योंकि ऑटोमैपर के पास आलसी लोडिंग (ResultSet_692D75838D4DC59B922F3E88CF1B10516CBF6CD8A32C4BE2F3FCC28CE83F0BD2) द्वारा बनाई गई प्रॉक्सी क्लास का मानचित्र नहीं है जो आपके ResultSet इकाई से प्राप्त होता है।

क्या आप कोशिश कर सकते हैं निम्नलिखित है:

public ActionResult Edit(ViewModel vm) 
{ 
    // This returns the entity proxy 
    MyEntity oldEntity = db.MyEntities.Find(vm.Id); 
    // i.e. Create a 'plain' Entity, not a proxy. 
    MyEntity newEntity = Mapper.Map<ViewModel, MyEntity>(vm); 

    db.Entry(oldEntity).CurrentValues.SetValues(newEntity); 
    // I don't think you need this now. 
    // db.Entry(entity).State = EntityState.Modified; 
    db.SaveChanges(); 
} 
+1

धन्यवाद @StuartLC में तय हो गई है। यह एक आसान कामकाज की तरह दिखता है। मेरा परिदृश्य थोड़ा अधिक जटिल है क्योंकि यह मुख्य इकाई की संग्रह संपत्ति में पंक्तियां हैं जिन्हें अपडेट किया जा रहा है, लेकिन यह आपके दृष्टिकोण और परीक्षण को अनुकूलित करेगा। –

+0

इसे फिर से देखकर, दुर्भाग्यवश, यह काम नहीं करेगा। CurrentValues.SetValues ​​का उपयोग करने में समस्या यह है कि यह लक्ष्य इकाई पर सभी गुणों को अपडेट करेगा। चूंकि व्यूमोडेल में सभी गुण नहीं होते हैं, इसलिए नई एंटीटी आंशिक रूप से आबादी होगी, और पुरानी एंटीटी पर नल या अन्य अमान्य मानों के साथ मानों को ओवरराइट कर देगा। –

+0

@PaulTaylor अच्छा बिंदु। अपने मूल कोड में, यदि आप 'Mapper.Map (vm, entity) को प्रतिस्थापित करते हैं, 'टाइप किए गए जेनेरिक' Mapper.Map (vm, entity) 'के साथ, संभवतः एएम गेंद बजाएगा? – StuartLC

1

तो क्या मैं अपने खुद के IMappable इंटरफेस और एक सरल सामान्य मानचित्रण उपयोगिता दो तरह मानचित्रण का समर्थन करने के रोलिंग था कर समाप्त हो गया। मैपिंग की जटिलता के आधार पर, आवश्यक कोड ऑटोमैपर से कम हो सकता है। नीचे दिए गए कोड:

public interface IMappable<TEntity, TViewModel> 
{ 
    void Map(TEntity source, TViewModel target); 
    void Map(TViewModel source, TEntity target); 
} 

public class ModelMapper<TEntity, TViewModel> where TEntity : new() where TViewModel : IMappable<TEntity, TViewModel>, new() 
{ 
    public static TViewModel Map(TEntity source) 
    { 
     TViewModel target = new TViewModel(); 
     Map(source, target); 
     return target; 
    } 

    public static TEntity Map(TViewModel source) 
    { 
     TEntity target = new TEntity(); 
     Map(source, target); 
     return target; 
    } 

    public static void Map(TEntity source, TViewModel target) 
    { 
     new TViewModel().Map(source, target); 
    } 

    public static void Map(TViewModel source, TEntity target) 
    { 
     new TViewModel().Map(source, target); 
    } 
} 

मेरे ViewModels के रूप में कई इकाई वर्गों के रूप में आवश्यक के लिए IMappable लागू, एक मानचित्र विधि को लागू प्रत्येक दिशा में आंकड़ा अंतरण को संभालने के लिए:

public class AddressView : IMappable<Address, AddressView> 
{ 
    public long AddressId { get; set; } 
    ... 

    #region "IMappable members" 
    public void Map(Address source, AddressView target) 
    { 
     target.AddressId = source.AddressId; 
     target.City = source.City; 
     target.FullAddress = source.FullAddress; 
     if (source.CountryId.HasValue) 
     { 
      target.Country = source.Country.Name; 
      target.CountryId = source.CountryId; 
     } 
     target.District = source.District; 
     target.Postcode = source.Postcode; 
     target.StreetName = source.StreetName; 
    } 

    public void Map(AddressView source, Address target) 
    { 
     target.AddressId = source.AddressId; 
     target.City = source.City; 
     target.CountryId = source.CountryId; 
     target.District = source.District; 
     target.Postcode = source.Postcode; 
     target.StreetName = source.StreetName; 
    } 
    #endregion 
}