Language: C#
QueryExtension
using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; using System.Linq; using LinqExtender.Attributes; using LinqExtender.Configuration.Serialization; using LinqExtender.Interfaces; namespace LinqExtender { /// <summary> /// Contains helper extensions for various query operations. /// </summary> public static class QueryExtension { private static readonly IDictionary<string, IDictionary<string, object>> uniqueDefaultValueObjectMap = new Dictionary<string, IDictionary<string, object>>(); internal static IDictionary<string, object> GetUniqueItemDefaultDetail(this IQueryObject obj) { Type runningType = obj.GetType(); if (!uniqueDefaultValueObjectMap.ContainsKey(runningType.Name)) { IDictionary<string, object> uniqueDefaultValues = new Dictionary<string, object>(); //clone the result. object runningObject = Activator.CreateInstance(runningType); ClassElement classElement = obj.GetClassElement(); PropertyInfo[] infos = runningType.GetProperties(); int index = 0; foreach (PropertyInfo info in infos) { if (info.Name != typeof (ClassElement).Name) { object[] arg = info.GetCustomAttributes(typeof (UniqueIdentifierAttribute), true); PropertyElement propertyElement = classElement.GetPropertyElement(info.Name); bool unique = propertyElement != null ? propertyElement.IsUnique : false; if ((arg != null && arg.Length > 0) || unique) { object value = info.GetValue(runningObject, null); if (!uniqueDefaultValues.ContainsKey(info.Name)) { uniqueDefaultValues.Add(info.Name, new {Index = index, Value = value}); break; } } index++; } } uniqueDefaultValueObjectMap.Add(runningType.Name, uniqueDefaultValues); } return uniqueDefaultValueObjectMap[runningType.Name]; } internal static bool EqualsDefault(this object targetValue, string propertyName, object source) { if (targetValue != null && (targetValue.GetType().IsPrimitive || targetValue.GetType().IsEnum)) { object @default = Activator.CreateInstance(source.GetType()); return @default.GetType().GetProperty(propertyName).GetValue(@default, null).Equals(targetValue); } return false; } internal static T Cast<T>(object obj, T type) { return (T)obj; } /// <summary> /// Tries to get <see cref="UnaryExpression"/> from <see cref="MethodCallExpression"/> /// </summary> /// <param name="expression"><see cref="Expression"/></param> /// <returns><see cref="UnaryExpression"/></returns> public static UnaryExpression GetUnaryExpressionFromMethodCall(this Expression expression) { MethodCallExpression mCall = expression as MethodCallExpression; UnaryExpression uExp = null; foreach (Expression exp in mCall.Arguments) { if (exp is UnaryExpression) { uExp = exp as UnaryExpression; break; } else if (exp is MethodCallExpression) { uExp = GetUnaryExpressionFromMethodCall(exp); break; } } return uExp; } /// <summary> /// tries to combine the values for a give a type . Ex User defined clasee /// and its properties. /// </summary> /// <param name="list"></param> /// <param name="type"></param> /// <returns></returns> public static object Combine(this IList<BucketItem.QueryCondition> list, Type type) { object combinedObject = Activator.CreateInstance(type); int index = 0; foreach (var condition in list) { condition.Value.CopyRecursive(combinedObject); index ++; } return combinedObject; } /// <summary> /// recursively copies object properties to destination. /// </summary> /// <param name="source"></param> /// <param name="destination"></param> public static void CopyRecursive(this object source , object destination) { PropertyInfo[] sourceProperties = source.GetType().GetProperties(); Type destType = destination.GetType(); foreach (PropertyInfo prop in sourceProperties) { if (prop.PropertyType.IsClass && !(prop.PropertyType.FullName.IndexOf("System") >= 0)) { object value = prop.GetValue(source, null); PropertyInfo destProp = destType.GetProperty(prop.Name); object destValue = destProp.GetValue(destination, null); if (value != null) { try { if (destValue == null) { destValue = Activator.CreateInstance(destProp.PropertyType); } // copy value.CopyRecursive(destValue); if (destProp.CanWrite) { destProp.SetValue(destination, destValue, null); } } catch { // skip } } } else { bool isDefault = false; object destValue = destType.GetProperty(prop.Name).GetValue(destination, null); if (destValue != null) { object tempObject = Activator.CreateInstance(destType); object tempValue = tempObject.GetType().GetProperty(prop.Name).GetValue(tempObject, null); isDefault = tempValue.Equals(destValue); } if (destValue == null || isDefault) { destType.GetProperty(prop.Name).SetValue(destination, prop.GetValue(source, null), null); } } } } internal static IEnumerable<PropertyInfo> GetBaseProperties(this Type target) { foreach (PropertyInfo propertyInfo in target.GetProperties()) { if (propertyInfo.Name != typeof(ClassElement).Name) yield return propertyInfo; } } internal static IQueryProvider GetQueryClass<T>(this T objectBase) where T : IQueryProvider { string key = objectBase.GetType().FullName; if (!_queryClases.ContainsKey(key)) { _queryClases.Add(key, objectBase); } return _queryClases[key] as IQueryProvider; } /// <summary> /// Tries to get a value from current expression. /// </summary> /// <param name="expression"></param> /// <returns></returns> public static object GetValueFromExpression(this Expression expression) { object value = null; UnaryExpression unaryExpression = GetUnaryExpressionFromMethodCall(expression); LambdaExpression lambdaExpression = unaryExpression.Operand as LambdaExpression; // get the value by dynamic invocation, used for getting value for MemberType expression. value = Expression.Lambda(lambdaExpression.Body).Compile().DynamicInvoke(); return value; } /// <summary> /// Invokes a method from an object. /// </summary> /// <param name="methodName"></param> /// <param name="itemType"></param> /// <param name="obj"></param> /// <returns></returns> public static object InvokeMethod(string methodName, Type itemType, object obj) { MemberInfo[] memInfos = itemType.GetMembers(); MethodInfo[] mInfos = itemType.GetMethods(); foreach (MethodInfo mInfo in mInfos) { if (string.Compare(methodName, mInfo.Name, false) == 0) { return itemType.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, null); } } return null; } private static object GetAttribute(Type type, ICustomAttributeProvider info) { object[] arg = info.GetCustomAttributes(type, true); if (arg != null && arg.Length > 0) { return arg[0]; } return null; } internal static bool IsEqual(object obj1, object obj2) { bool equal = true; IEnumerable<PropertyInfo> infos = obj1.GetType().GetBaseProperties(); ClassElement element = obj1.GetClassElement(); foreach (PropertyInfo info in infos) { IgnoreAttribute queryAttribute = GetAttribute(typeof(IgnoreAttribute), info) as IgnoreAttribute; PropertyElement propertyElement = element.GetPropertyElement(info.Name); bool ignore = propertyElement != null ? propertyElement.Ignore : false; if (queryAttribute == null && !ignore) { object value1 = info.GetValue(obj1, null); object value2 = info.GetValue(obj2, null); if (Convert.ToString(value2) != Convert.ToString(value1)) { equal = false; } } } return equal; } internal static PropertyElement GetPropertyElement (this ClassElement classElement, string propertyName) { if (classElement != null && classElement.PropertyDictionary.ContainsKey(propertyName)) return classElement.PropertyDictionary[propertyName]; return null; } internal static ClassElement GetClassElement(this object queryObject) { PropertyInfo info = queryObject.GetType().GetProperty("ClassElement"); if (info != null) { return (ClassElement) info.GetValue(queryObject, null); } return null; } /// <summary> /// Gets a property name for <see cref="PropertyInfo"/> including <see cref="OriginalFieldNameAttribute"/> /// </summary> /// <param name="info"></param> /// <param name="target">target query object.</param> /// <returns></returns> public static string GetPropertyName(this PropertyInfo info, object target) { string fieldName = string.Empty; object[] arg = info.GetCustomAttributes(typeof(OriginalFieldNameAttribute), true); if (arg != null && arg.Length > 0) { var fieldNameAttr = arg[0] as OriginalFieldNameAttribute; if (fieldNameAttr != null) fieldName = fieldNameAttr.FieldName; } else { PropertyElement propertyElement = target.GetClassElement().GetPropertyElement(info.Name); if (propertyElement != null && !string.IsNullOrEmpty(propertyElement.AttributeName)) { fieldName = propertyElement.AttributeName; } else { fieldName = info.Name; } } return fieldName; } /// <summary> /// Converts the array to propery dictonary. /// </summary> /// <param name="elements"></param> /// <returns></returns> internal static IDictionary<string, PropertyElement> ToPropertyElementDictionary(this PropertyElement[] elements) { IDictionary<string, PropertyElement> dictionary = new Dictionary<string, PropertyElement>(); foreach (PropertyElement element in elements) { dictionary.Add(element.Name, element); } return dictionary; } /// <summary> /// Gets <see cref="MemberInfo"/> from <see cref="Expression{TDelegate}"/> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="expression"></param> /// <returns><see cref="MemberInfo"/></returns> internal static MemberInfo GetMemberFromExpression<T>(this Expression<Func<T, object>> expression) { if (expression.Body is MemberExpression) { MemberExpression memberExpression = (MemberExpression) expression.Body; return memberExpression.Member; } else { UnaryExpression unaryExpression = (UnaryExpression) expression.Body; if (unaryExpression.Operand is MemberExpression) { MemberExpression memberExpression = (MemberExpression) unaryExpression.Operand; return memberExpression.Member; } } return null; } private static IDictionary<string, object> _queryClases = new Dictionary<string, object>(); } }
Tags:
Report Abuse
Subscribe
Discuss
What's new
What is it
New Snippet
Recent Snippets
My Snippets
Web Code
Search

