2

I was trying to find a way to save the object posted to a web service to a database managed by entity.

Instead of copying each property manually, I wanted a way to copy all properties without me doing much code.

Ex: objectFromClient.Copy(objectToDatabase);

This would save me multiple lines of code to copy each property. I liked the suggested code given in this question.

Apply properties values from one object to another of the same type automatically?

However this didnt work on objects tracked by Entity since the Key properties can not be modified in Entity.

I made some amendments to skip those columns which are tagged as EntityKey.

I am not sure if this was a correct approach. Can somebody comment?

using System;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Reflection;
/// <summary>
/// A static class for reflection type functions
/// </summary>
public static class Reflection
{
    /// <summary>
    /// Extension for 'Object' that copies the properties to a destination object.
    /// </summary>
    /// <param name="source">The source.</param>
    /// <param name="destination">The destination.</param>
    public static void CopyProperties(this object source, object destination)
    {
        // If any this null throw an exception
        if (source == null || destination == null)
            throw new Exception("Source or/and Destination Objects are null");
        // Getting the Types of the objects
        Type typeDest = destination.GetType();
        Type typeSrc = source.GetType();
        // Collect all the valid properties to map
        var results = from srcProp in typeSrc.GetProperties()
                      let targetProperty = typeDest.GetProperty(srcProp.Name)
                      where srcProp.CanRead
                      && targetProperty != null
                      && (targetProperty.GetSetMethod(true) != null && !targetProperty.GetSetMethod(true).IsPrivate)
                      && (targetProperty.GetSetMethod().Attributes & MethodAttributes.Static) == 0
                      && targetProperty.PropertyType.IsAssignableFrom(srcProp.PropertyType)
                      && targetProperty.GetCustomAttributes(false).Where(a => a is EdmScalarPropertyAttribute && ((EdmScalarPropertyAttribute)a).EntityKeyProperty).Count() == 0
                      && srcProp.Name != "EntityKey" 
                      select new { sourceProperty = srcProp, targetProperty = targetProperty };
        //map the properties
        foreach (var props in results)
        {
            //System.Diagnostics.Debug.WriteLine(props.targetProperty.Name);
            props.targetProperty.SetValue(destination, props.sourceProperty.GetValue(source, null), null);
        }
    }
}
Community
  • 1
  • 1
Vasu Inukollu
  • 120
  • 1
  • 3
  • 10
  • 1
    If this code has problems you know of, you may want to post them here. If this code works and you are looking for a review, you might be better off over at [Code Review](http://codereview.stackexchange.com/). – nvoigt Mar 17 '16 at 07:58

2 Answers2

5

This function will copy properties from one object to other.

private static Target CopyProperties<Source, Target>(Source source, Target target)
    {
        foreach (var sProp in source.GetType().GetProperties())
        {
            bool isMatched = target.GetType().GetProperties().Any(tProp => tProp.Name == sProp.Name && tProp.GetType() == sProp.GetType() && tProp.CanWrite);
            if (isMatched)
            {
                var value = sProp.GetValue(source);
                PropertyInfo propertyInfo = target.GetType().GetProperty(sProp.Name);
                propertyInfo.SetValue(target, value);
            }
        }
        return target;
    }
Prateek Gupta
  • 880
  • 1
  • 10
  • 21
4

Instead of copying each property manually, I wanted a way to copy all properties without me doing much code.

Have you tried with AutoMapper? Check this link.

AutoMapper is a simple little library built to solve a deceptively complex problem - getting rid of code that mapped one object to another.

I use it everywhere, it's quite useful to get rid of code like the one you had to write :)

Luca Ghersi
  • 3,261
  • 18
  • 32