csla 3.6.2 --> DataMapper.Map giving an exception

csla 3.6.2 --> DataMapper.Map giving an exception

Old forum URL: forums.lhotka.net/forums/t/6671.aspx


rfcdejong posted on Wednesday, March 25, 2009

I remember trying this before and i gave up, but now i want to try to get it working.

In my ObjectFactoryBase class i want to support automatic mapping from BO to DTO and visa versa all based on a mappingdefinition. That'll work for sure as long the developers from my company do write the mapping once foreach business object.

Csla offers a nice DataMapper static helper class which i wanted to use, it seems like it does dynamic stuff so reflection is just once and then dynamic in memory with IL stuff. Oke.
Using DataMap.Load won't do because that does a ReadProperty on each managed property, even if they are LazyLoaded.

My code:

DataMap dm = new DataMap(BOType, DTOType);
Dictionary<object, object> sourcevalues = GetSourceDictionary(boObj, properties);
foreach (IPropertyPart part in properties)
{
dm.AddPropertyMapping(property.BOProperty.Name, property.DTOProperty);
}
DataMapper.Map(sourcevalues, dto, dm);

results into an exception

"AccessViolationException was unhandled"
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

happens at DataMapper line 268

object value = mapping.FromMemberHandle.DynamicMemberGet(source);

All seems to be good, i see no reason why this exception is being thrown :(

rfcdejong replied on Wednesday, March 25, 2009

btw, i think it goes wrong with the type's being passed into the DataMap constructor. Using IDictionary as source should be sourceValues.GetType()
But that just results into MemberInfo.GetProperty returning null.

Is there any example in how to use the DataMapper in combination with a IDictionary as source?

rfcdejong replied on Thursday, March 26, 2009

Nevermind, i figured it out.
Using the DataMap class isn't needed when Mapping by an Dictionary.

Giving a 3rd parameter caused another overloaded method to be called, with object as parameter. Well it isn't giving an correct exception, but that's all.

All i needed to do:

private Dictionary<string, object> GetDictionary(BO obj, List<IPropertyPart> properties, bool isInserting)
{
   var result = new Dictionary<string, object>();
   foreach (IPropertyPart part in properties)
   {
      var identity = (part as IIdentityPart);
      if ((identity == null) || (identity != null && isInserting))
      {
         var value = ReadProperty(obj, part.BOProperty);
         result.Add(part.DTOProperty, value);
      }
   }
   
return result;
}

...
List<IPropertyPart> properties = map.Properties.FindAll(x => x.DTOType == property.DTOType);
Dictionary<string, object> dictionary = GetDictionary(obj, properties, true);
DataMapper.Map(dictionary, dto);
Repository.Save(dto);

Copyright (c) Marimer LLC