public Expression CreateInitExpression() { List <MemberBinding> bindings = new List <MemberBinding>(); var modelType = ((PropertyInfo)ModelProperty.Member).PropertyType; var responseType = ResponseProperty.PropertyType; var props = responseType.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(x => x.CanWrite); foreach (var p in props) { IncludeTree include; Expression bind = null; if (!Includes.TryGetValue(p.Name, out include)) { NavigationPropertyAttribute navAttr = p.GetCustomAttribute <NavigationPropertyAttribute>(); if (navAttr != null) { var navModelProp = Expression.Property(ModelProperty, modelType.GetProperty(navAttr.NavigationProperty)); var navProp = Expression.Property(navModelProp, ((PropertyInfo)navModelProp.Member).PropertyType.GetProperty(navAttr.Property)); bind = navProp; } else if (IsMappeable(p)) { bind = Expression.Property(ModelProperty, modelType.GetProperty(p.Name)); } } else { bind = include.CreateInitExpression(); } if (bind != null) { bindings.Add(Expression.Bind(p, bind)); } } NewExpression newResponse = Expression.New(responseType); MemberInitExpression initExpression = Expression.MemberInit(newResponse, bindings); return(initExpression); }
public Expression <Func <T, TResponse> > Select <TResponse>(string include = null) { List <MemberBinding> bindings = new List <MemberBinding>(); foreach (var p in ResponseType.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(x => x.CanWrite)) { NavigationPropertyAttribute navAttr = p.GetCustomAttribute <NavigationPropertyAttribute>(); if (navAttr != null) { bindings.Add(Expression.Bind(p, Expression.Property(Expression.Property(Parameter, navAttr.NavigationProperty), navAttr.Property))); } else if (IncludeTree.IsMappeable(p)) { bindings.Add(Expression.Bind(p, Expression.Property(Parameter, p.Name))); } } if (!string.IsNullOrWhiteSpace(include)) { var incTrees = IncludeTree.Build(include, ResponseType, ModelType, Parameter); foreach (var item in incTrees) { bindings.Add(Expression.Bind(item.ResponseProperty, item.CreateInitExpression())); } } MemberInitExpression initExpression = Expression.MemberInit(Expression.New(typeof(TResponse)), bindings); Expression current = Parameter; while (current != null && !(current is ParameterExpression)) { current = ((MemberExpression)current).Expression; } return(Expression.Lambda <Func <T, TResponse> >(initExpression, (ParameterExpression)current)); }