Aquí hay un par de métodos de extensión que he improvisado juntos para convertir IQueryables y IEnumerables de un tipo a otro (es decir DTO) Se usa principalmente para convertir de un tipo más grande (es decir, el tipo de la fila en la base de datos que tiene campos innecesarios) a uno más pequeño.
Los aspectos positivos de este enfoque son:
- prácticamente no requiere código para utilizar - una simple llamada a .Transform
<DtoType>
() es todo lo que necesita
- funciona igual que .Elija (s => new {...}) es decir, cuando se usa con IQueryable produce el código SQL óptimo, excluyendo los campos Type1 que DtoType no tiene.
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>();
}
Entonces, ¿qué falla si usa FindByAll (...). Seleccione (s => nuevo {ID = ID., Nombre = s.Name}). ToList()? –
Tenga en cuenta también el comentario en mi respuesta sobre la creación de su propio tipo si es necesario. Json.NET podría exigir propiedades editables, en cuyo caso necesitará su propio tipo (los tipos anónimos de C# son inmutables). –