/// <summary> /// /// </summary> /// <param name="dataIndices"></param> /// <returns></returns> public Expression <Func <T, object> > GetExpression(IDictionary <int, string> dataIndices) { // Get type of root object Type type = typeof(T); ParameterExpression parentParameterExpression = Expression.Parameter(type, "x"); MemberExpression memberExpression = default(MemberExpression); // Loop through each node IOrderedEnumerable <KeyValuePair <int, string> > orderedList = dataIndices.OrderBy(x => x.Key); for (int i = 0; i < dataIndices.Count; i++) { // Get the current record in the loop string dataIndex = orderedList.ElementAt(i).Value; // If this is the first iteration, just set the variable - else append the expa memberExpression = i == 0 ? Expression.PropertyOrField(parentParameterExpression, dataIndex) : Expression.PropertyOrField(memberExpression, dataIndex); // Check if the last field corresponds to a complex type or a standard type (struct) if (i != dataIndices.Count - 1) { continue; } // Use some reflection to capture the class' and properties metadata PropertyInfo propertyInfo = (PropertyInfo)memberExpression.Member; bool isReferenceType = propertyInfo != null && !propertyInfo.PropertyType.GetTypeInfo().IsValueType && !propertyInfo.PropertyType.GetTypeInfo().IsPrimitive && propertyInfo.PropertyType != typeof(string); if (!isReferenceType) { continue; } DefaultDisplayAttribute classDefaultDisplayAttribute = propertyInfo .PropertyType .GetTypeInfo() .GetCustomAttribute <DefaultDisplayAttribute>(); if (classDefaultDisplayAttribute != null) { memberExpression = Expression.PropertyOrField(memberExpression, classDefaultDisplayAttribute.Name); } } UnaryExpression sortExpression = Expression.Convert(memberExpression, typeof(object)); return(Expression.Lambda <Func <T, dynamic> >(sortExpression, parentParameterExpression)); }
/// <summary> /// Inspects the property type and overrides the property field by the value specified in the default display attribute. /// </summary> /// <param name="memberField">The member field to inspect</param> /// <returns>The member expression</returns> internal static MemberExpression OverrideWithDefaultDisplay(this MemberExpression memberField) { // Check the type of the property PropertyInfo propertyInfo = memberField.Member as PropertyInfo; bool isPropertyReferenceType = propertyInfo != null && propertyInfo.PropertyType != typeof(string) && !propertyInfo.PropertyType.GetTypeInfo().IsValueType && !propertyInfo.PropertyType.GetTypeInfo().IsPrimitive; if (!isPropertyReferenceType) { return(memberField); } DefaultDisplayAttribute classDefaultDisplayAttribute = propertyInfo .PropertyType .GetTypeInfo() .GetCustomAttribute <DefaultDisplayAttribute>(); return(classDefaultDisplayAttribute != null ? Expression.PropertyOrField(memberField, classDefaultDisplayAttribute.Name) : null); }