|
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using System.Linq.Expressions; |
|
|
|
namespace DynamicMapping |
|
{ |
|
public static class DynamicLINQExtensions |
|
{ |
|
/// <summary> |
|
/// Creates a DynamicQueryable<T> from the query using the supplied column mappings |
|
/// </summary> |
|
/// <typeparam name="T"></typeparam> |
|
/// <param name="query"></param> |
|
/// <param name="columnMappings"></param> |
|
/// <returns></returns> |
|
public static IDynamicQueryable<T> AsDynamicQuery<T>(this IQueryable<T> query, IDictionary<string, string> columnMappings) |
|
{ |
|
return new DynamicQueryable<T>(query, columnMappings); |
|
} |
|
|
|
/// <summary> |
|
/// Projects each element of a sequence into a new form. Specify the mappings using the mapAction parameter. |
|
/// </summary> |
|
/// <typeparam name="T"></typeparam> |
|
/// <typeparam name="TResult"></typeparam> |
|
/// <param name="query"></param> |
|
/// <param name="mapAction"></param> |
|
/// <returns></returns> |
|
public static IDynamicQueryable<TResult> SelectAs<T, TResult>(this IDynamicQueryable<T> query, Action<DynamicMapper<T, TResult>> mapAction) |
|
{ |
|
var mappings = query.Mappings; |
|
var mapper = new DynamicMapper<T, TResult>(mappings); |
|
mapAction(mapper); |
|
var squery = query.Select(mapper.GetMappingTransform()); |
|
return new DynamicQueryable<TResult>(squery, mappings); |
|
} |
|
|
|
|
|
/// <summary> |
|
/// Projects each element of a sequence into a new form, using the specified DynamicMapper |
|
/// </summary> |
|
/// <typeparam name="T"></typeparam> |
|
/// <typeparam name="TResult"></typeparam> |
|
/// <param name="query"></param> |
|
/// <param name="dynamicMapper"></param> |
|
/// <returns></returns> |
|
public static IQueryable<TResult> SelectAs<T, TResult>(this IDynamicQueryable<T> query, DynamicMapper<T, TResult> dynamicMapper) |
|
{ |
|
return query.Select(dynamicMapper.GetMappingTransform()); |
|
} |
|
|
|
/// <summary> |
|
/// Returns an instance of each element in a sequence with only the properties mapped by the specified column names populated |
|
/// </summary> |
|
/// <typeparam name="T"></typeparam> |
|
/// <param name="query"></param> |
|
/// <param name="columnNames"></param> |
|
/// <returns></returns> |
|
public static IDynamicQueryable<T> SelectFields<T>(this IDynamicQueryable<T> query, IEnumerable<string> columnNames) |
|
{ |
|
var mappings = query.Mappings; |
|
var propertyNames = columnNames.Select(x => mappings[x]); |
|
var newquery = query.Select(CreateDynamicNewExpression<T>(propertyNames)); |
|
return new DynamicQueryable<T>(newquery, mappings); |
|
} |
|
|
|
/// <summary> |
|
/// Sorts elements of a sequence in ascending order according a specified column name |
|
/// </summary> |
|
/// <typeparam name="T"></typeparam> |
|
/// <param name="query"></param> |
|
/// <param name="columnName"></param> |
|
/// <returns></returns> |
|
public static IDynamicQueryable<T> OrderByField<T>(this IDynamicQueryable<T> query, string columnName) |
|
{ |
|
var mappings = query.Mappings; |
|
var propertyName = mappings[columnName]; |
|
var newquery = query.OrderBy(CreateDynamicPropertyExpression<T, object>(propertyName)); |
|
return new DynamicQueryable<T>(newquery, mappings); |
|
} |
|
|
|
/// <summary> |
|
/// Consecutively sorts elements of a sequence in ascending order according to a list of column names in the order that they appear |
|
/// </summary> |
|
/// <typeparam name="T"></typeparam> |
|
/// <param name="query"></param> |
|
/// <param name="columnNanes"></param> |
|
/// <returns></returns> |
|
public static IDynamicQueryable<T> OrderByFields<T>(this IDynamicQueryable<T> query, IEnumerable<string> columnNanes) |
|
{ |
|
var mappings = query.Mappings; |
|
var propertyNames = columnNanes.Select(x => mappings[x]); |
|
foreach (var propertyName in propertyNames) |
|
{ |
|
var newquery = query.OrderBy(CreateDynamicPropertyExpression<T, object>(propertyName)); |
|
query = new DynamicQueryable<T>(newquery, mappings); |
|
} |
|
return query; |
|
} |
|
|
|
/// <summary> |
|
/// Creates an expression that returns the property specified by the propertyName parameter |
|
/// </summary> |
|
/// <typeparam name="T">The containing type of the property</typeparam> |
|
/// <typeparam name="TResult"></typeparam> |
|
/// <param name="propertyName"></param> |
|
/// <returns></returns> |
|
private static Expression<Func<T, TResult>> CreateDynamicPropertyExpression<T, TResult>(string propertyName) |
|
{ |
|
var parameter = Expression.Parameter(typeof(T)); |
|
var body = Expression.Property(parameter, propertyName); |
|
return Expression.Lambda<Func<T, TResult>>(body, false, parameter); |
|
} |
|
|
|
/// <summary> |
|
/// Creates a New object expression with only the members specified by the proprtyNames parameter initalized |
|
/// </summary> |
|
/// <typeparam name="T">The type of object to create</typeparam> |
|
/// <param name="propertyNames">A list of member names on the type</param> |
|
/// <returns></returns> |
|
private static Expression<Func<T, T>> CreateDynamicNewExpression<T>(IEnumerable<string> propertyNames) |
|
{ |
|
var body = Expression.New(typeof(T).GetConstructor(new Type[] { })); |
|
var parameter = Expression.Parameter(typeof(T)); |
|
var bindings = new List<MemberBinding>(); |
|
foreach (var propertyName in propertyNames) |
|
{ |
|
bindings.Add(Expression.Bind(typeof(T).GetProperty(propertyName), Expression.Property(parameter, propertyName))); |
|
} |
|
var memberinit = Expression.MemberInit(body, bindings); |
|
// returns a delegate x => new T() { Field1 = x.Field1, Field2 = x.Field2 ... } |
|
return Expression.Lambda<Func<T, T>>(memberinit, false, parameter); |
|
} |
|
|
|
} |
|
} |
Thanks for sharing!