lundi 22 mai 2017

Copy values of an object of one type to an object of another using C# reflection

I have been tasked with writing a routine against an existing database. This database has several tables that have identical structures, but different names (I did not design this, please do not suggest database design change). I am writing this in EF, and the models were created database-first.

The best option I can think of for this situation is to create a class that has the exact same properties, and create a routine that can accept generic types to copy data from the EF model to the generic model.

My models:

    // Sample EF database-first created model
    namespace SampleDataModel.Models
    {
        using System;
        using System.Collections.Generic;

        public partial class SampleClassFlavorOne
        {
            public int Id {get; set;}
            public string PropertyOne {get; set;}
            public string Property2 {get; set;}
            public DateTime Property3 {get; set;}
        }
    }

    // Sample of generic class I created
    public class GenericSampleClass{
        public int Id {get; set;}
        public string PropertyOne {get; set;}
        public string Property2 {get; set;}
        public DateTime Property3 {get; set;}
    }

My routine:

        private static void CopyFlavorToGenericList<T1, T2>(List<T1> fromList, List<T2> toList){
        foreach (var t in fromList)
        {
            //(As you can see, I have tried entering the foreach loop a both ways
            //foreach (var p in typeof(T1).GetProperties())

            foreach (var p in typeof(T2).GetProperties())
            {
                if (p != null && p.CanWrite)
                {
                    dynamic newObject = null;
                    p.SetValue((T2)newObject, p.GetValue(t, null), null);
                }
            }

            toList.Add(toObject);
        }
    }

Implementing the routine:

switch (flavor){
        case "FlavorOne":
            List<SampleClassFlavorOne> _baseFlavor = db.SampleClassFlavorOne.ToList();
            List<GenericSampleClass> _genericFlavor = new List<GenericSampleClass>();

            CopyFlavorToGenericList<SampleClassFlavorOne, GenericSampleClass>(_baseFlavor, _genericFlavor);
            break;
    }

No matter what I try, I always get:

An exception of type 'System.Reflection.TargetException' occurred in mscorlib.dll but was not handled in user code. Additional information: Object does not match target type.

I cannot figure out what I am missing.

  1. What may I be missing?
  2. Am I going about this the wrong way? If so, what is the correct way to do what I want to do given these conditions?

Any help appreciated, thanks!





Aucun commentaire:

Enregistrer un commentaire