通用业务到ORM对象映射功能

时间:2011-07-16 14:11:54

标签: c# generics orm

我有2个对象, BusinessCustomer ORMCustomer

我希望能够在我的业务层活动中将一个映射到另一个,例如

  • 假如我从db加载 ORMCustomer ,我想填充 BusinessCustomer
  • 或者如果我正在处理 BusinessCustomer 并希望继续使用db我想填充 ORMCustomer

在我的业务层中,我希望能够像:

Mapper.MapCustomer( src target

然后,MapCustomer方法可以决定映射的方向 BusinessCustomer-> ORMCustomer ORMCustomer-> BusinessCustomer

我一直在修补Generics,但我似乎无法找到一个合适的解决方案,如何在 Mapper 类中实现它。

internal void MapCustomer<T, K>(T src, K target)
{
  if (src.GetType() == typeof(BusinessCustomer)) 
  { 
    MapBusinessCustomerToORMCustomer(src, target);
  }
  else if (src.GetType() == typeof(ORMCustomer)) 
  {
    MapORMCustomerToBusinessCustomer(src, target);
  }
}

有关如何最好地实现这一点的想法吗?

3 个答案:

答案 0 :(得分:1)

这是我为这样的任务写的简单的事情。属性名称必须相同。

public static class TypeConverter
{
    /// <summary>
    /// Instantiates a new DestinationType copying all public properties with the same type and name from the SourceType.
    /// The destination object must have a parameter less constructor.
    /// </summary>
    /// <param name="sourceObject">The source object.</param>
    /// <param name="destinationType">Type of the destination object.</param>
    public static DestinationType Convert<SourceType, DestinationType>(SourceType sourceObject, Type destinationType)
    {
        if (destinationType.GetConstructors().Where(x => x.GetParameters().Count() == 0).Count() == 0)
            throw new Exception("A parameter less constructor is required for the destination type.");

        // instantiate the destination object

        DestinationType destinationObject = Activator.CreateInstance<DestinationType>();

        // get all public properties from the source and destination object

        IEnumerable<PropertyInfo> sourceProps = sourceObject.GetType().GetProperties().Where(x => x.PropertyType.IsPublic);

        IEnumerable<PropertyInfo> destinationProps = destinationType.GetProperties().Where(x => x.PropertyType.IsPublic || x.PropertyType.IsEnum);

        // copy the public properties that exist in both the source type and destination type

        foreach (PropertyInfo prop in destinationProps)
        {
            PropertyInfo sourceProp = sourceProps.SingleOrDefault(x => x.Name == prop.Name);

            if (sourceProp != null)
            {
                try
                {
                    object propValue = new object();
                    if (prop.PropertyType.IsEnum)
                    {
                        propValue = Enum.Parse(prop.PropertyType, sourceProp.GetValue(sourceObject, null).ToString());

                    }
                    else
                    {
                        propValue = System.Convert.ChangeType(sourceProp.GetValue(sourceObject, null), prop.PropertyType);
                    }


                    prop.SetValue(destinationObject, propValue, null);
                }
                catch { }
            }
        }

        return destinationObject;
    }

    /// <summary>
    /// Instantiates a new DestinationType copying all public properties with the same type and name from the SourceType.
    /// The destination object must have a parameter less constructor.
    /// </summary>
    /// <param name="sourceObject">The collection of source objects.</param>
    /// <param name="destinationType">Type of the destination object.</param>
    public static IEnumerable<DestinationType> Convert<SourceType, DestinationType>(IEnumerable<SourceType> sourceObjects, Type destinationType)
    {
        List<DestinationType> convertedObjecs = new List<DestinationType>();

        List<SourceType> sourceObjectList = sourceObjects.ToList();

        foreach (SourceType item in sourceObjectList)
            convertedObjecs.Add(Convert<SourceType, DestinationType>(item, destinationType));

        return convertedObjecs;
    }
}

答案 1 :(得分:1)

您无需重新发明轮子。 AutoMapper这样做。

答案 2 :(得分:0)

我过去曾经用过这个。它很简单,非常快,因为它只反映一次类型,然后发出从那一点开始使用的get / set代码。

http://thatstoday.com/a/1451753