Voici quelques méthodes d'extension que j'ai assemblées pour convertir les IQueryables et les IEnumerables d'un type à un autre (c'est-à-dire un DTO). Cette méthode est principalement utilisée pour convertir un type plus grand (c'est-à-dire le type de la ligne dans la base de données qui a des champs inutiles) en un type plus petit.
Les aspects positifs de cette approche sont les suivants :
- son utilisation ne nécessite pratiquement pas de code - un simple appel à .Transform
<DtoType>
() est tout ce dont vous avez besoin
- il fonctionne comme .Select(s=>new{...}), c'est-à-dire que lorsqu'il est utilisé avec IQueryable, il produit le code SQL optimal, à l'exclusion des champs Type1 que DtoType n'a pas.
LinqHelper.cs :
public static IQueryable<TResult> Transform<TResult>(this IQueryable source)
{
var resultType = typeof(TResult);
var resultProperties = resultType.GetProperties().Where(p => p.CanWrite);
ParameterExpression s = Expression.Parameter(source.ElementType, "s");
var memberBindings =
resultProperties.Select(p =>
Expression.Bind(typeof(TResult).GetMember(p.Name)[0], Expression.Property(s, p.Name))).OfType<MemberBinding>();
Expression memberInit = Expression.MemberInit(
Expression.New(typeof(TResult)),
memberBindings
);
var memberInitLambda = Expression.Lambda(memberInit, s);
var typeArgs = new[]
{
source.ElementType,
memberInit.Type
};
var mc = Expression.Call(typeof(Queryable), "Select", typeArgs, source.Expression, memberInitLambda);
var query = source.Provider.CreateQuery<TResult>(mc);
return query;
}
public static IEnumerable<TResult> Transform<TResult>(this IEnumerable source)
{
return source.AsQueryable().Transform<TResult>();
}