I have created a Extension method for IQueryable class to convert list of a Generic source class to list of other generic destination class,(.net3.5)
I’m using reflection to get properties from source object value and assign it to destinvation object.
The source code of the class is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text.RegularExpressions;
namespace System.Linq
{
public static class QueryableExtensions
{
public static IQueryable<TDest> ToDTO<TDest>(this IQueryable<TSource> source)//getting error on this line
{
return DTOTranslator<TDest>.ConvertToDTO<TDest>(source);
}
}
public class DTOTranslator<TSource>
{
public static IQueryable<TDest> ConvertToDTO<TDest>(IQueryable<TSource> source)
{
List<TDest> destinationList = new List<TDest>();
List<TSource> sourceList = source.ToList<TSource>();
var sourceType = typeof(TSource);
var destType = typeof(TDest);
foreach (TSource sourceElement in sourceList)
{
TDest destElement = Activator.CreateInstance<TDest>();
//Get all properties from the object
PropertyInfo[] sourceProperties = typeof(TSource).GetProperties();
foreach (PropertyInfo sourceProperty in sourceProperties)
{
//and assign value to each propery according to property name.
PropertyInfo destProperty = destType.GetProperty(sourceProperty.Name);
destProperty.SetValue(destElement, sourceProperty.GetValue(sourceElement, null), null);
destinationList.Add(destElement);
}
}
return destinationList.AsQueryable();
}
}
}
however at compile time I am getting the error on line 12:
The type or namespace name 'TSource' could not be found (are you missing a using directive or an assembly reference?)
UPDATE:
Thanks to all for reply.
Now I’ve updated my class as follows:
public static class QueryableExtensions
{
public static IQueryable<TDest> ToDTO<TSource, TDest>(this IQueryable<TSource> source)
{
List<TDest> destinationList = new List<TDest>();
List<TSource> sourceList = source.ToList<TSource>();
var sourceType = typeof(TSource);
var destType = typeof(TDest);
foreach (TSource sourceElement in sourceList)
{
TDest destElement = Activator.CreateInstance<TDest>();
//Get all properties from the object
PropertyInfo[] sourceProperties = typeof(TSource).GetProperties();
foreach (PropertyInfo sourceProperty in sourceProperties)
{
//and assign value to each propery according to property name.
PropertyInfo destProperty = destType.GetProperty(sourceProperty.Name);
destProperty.SetValue(destElement, sourceProperty.GetValue(sourceElement, null), null);
destinationList.Add(destElement);
}
}
return destinationList.AsQueryable();
}
}
This works fine,
now the only thing I wonder is that-
Is it possible to skip the <TSource> paramerter,
how to read it from the IQueryable’s element type and define its object?
I mean currently I call the method as
IQueryable<CATEGORY_DTO> dtos = (from p in new MyEntities().CATEGORY select p).ToDTO<CATEGORY, CATEGORY_DTO>();
I want to call it as
IQueryable<CATEGORY_DTO> dtos = (from p in new MyEntities().CATEGORY select p).ToDTO<CATEGORY_DTO>();
Thanks, NJ
Try this:
The addition being that the
ToDTOmethod also references theTSourcegeneric type (since otherwise how can you reference is as a parameter – this led to the original error), and this generic type is given in the constructor forDTOTranslator(since it is an error to useTDestin the constructor, as the definition of the generic type needed in the constructor itself isTSource, which is a different type fromTDest).