public static IQueryable SelectByInterface <T>(this IQueryable <T> source, Type interfaceType, bool includeTypeName = true) { var properties = interfaceType.GetPublicProperties().Where(each => each.PropertyType.IsSimple()).ToList(); var objectFields = properties.Select(each => each.Name).ToList(); if (includeTypeName) { objectFields.Add("_Type"); } var sourceType = source.GetType().GetGenericArguments().First(); var param = Expression.Parameter(sourceType); var expressions = new List <MemberBinding>(); lock (RuntimeTypes) { if (!RuntimeTypes.ContainsKey(interfaceType)) { var runtimeType = new RuntimeObjectBuilder().CreateNewObject(interfaceType, interfaceType, objectFields.ToArray()).GetType(); RuntimeTypes.Add(interfaceType, runtimeType); } var instance = Activator.CreateInstance(RuntimeTypes[interfaceType]); var type = instance.GetType(); if (includeTypeName) { var typeProperty = type.GetProperty("_Type"); expressions.Add(Expression.Bind(typeProperty, Expression.Constant(typeof(T).Name))); } foreach (var property in instance.GetType().GetProperties()) { if (property.Name.StartsWith("_")) { continue; } expressions.Add(Expression.Bind(property, Expression.PropertyOrField(param, property.Name))); } var init = Expression.MemberInit(Expression.New(instance.GetType()), expressions.ToArray()); var func = typeof(Func <,>).MakeGenericType(typeof(T), type); var lambdaMethods = typeof(Expression).GetMethods().Where(each => each.Name == "Lambda"); var expression = lambdaMethods.First().MakeGenericMethod(func).Invoke(null, new object[] { init, new[] { param } }) as Expression; //var expression = Expression.Lambda<Func<T, I>>(init, param); var methods = typeof(Queryable).GetMethods().Where(each => each.Name == "Select").ToList(); var method = methods.FirstOrDefault().MakeGenericMethod(typeof(T), type); return(method.Invoke(null, new object[] { source, expression }) as IQueryable); } }
public static IQueryable <BaseRuntimeObject> DynamicSelect <T, G>(this IQueryable <IGrouping <G, T> > source, string groupName, params string[] propertyNames) { var objectFields = new List <string>(propertyNames); objectFields.Add(groupName); var sourceType = source.GetType().GetGenericArguments().First(); var param = Expression.Parameter(sourceType); var expressions = new List <MemberBinding>(); var instance = new RuntimeObjectBuilder().CreateNewObject(typeof(T), null, objectFields.ToArray()); var type = instance.GetType(); var groupProperty = type.GetProperty(groupName); foreach (var propertyName in propertyNames) { var property = type.GetProperty(propertyName); var sumMethod = typeof(Enumerable).GetMethods() .FirstOrDefault(x => x.Name == "Sum" && x.ContainsGenericParameters && x.ReturnType == property.PropertyType); if (sumMethod != null) { var eachEntity = Expression.Parameter(typeof(T), "each"); var propertyAccess = Expression.Property(eachEntity, propertyName); var lambda = Expression.Lambda(propertyAccess, eachEntity); var sumExpression = Expression.Call(sumMethod.MakeGenericMethod(typeof(T)), param, lambda); expressions.Add(Expression.Bind(property, sumExpression)); } else { expressions.Add(Expression.Bind(property, Expression.PropertyOrField(param, propertyName))); } } expressions.Add(Expression.Bind(groupProperty, Expression.PropertyOrField(param, "Key"))); var init = Expression.MemberInit(Expression.New(instance.GetType()), expressions.ToArray()); var expression = Expression.Lambda <Func <IGrouping <G, T>, BaseRuntimeObject> >(init, param); return(source.Select(expression)); }