#region License Information /* HeuristicLab * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using HeuristicLab.Services.OKB.DataAccess; namespace HeuristicLab.Services.OKB.AttributeSelection { public static class ExpressionTools { /// /// p => f(g(p)) where p : T /// public static LambdaExpression CallAfter(Expression f, Expression g) { ParameterExpression p = Expression.Parameter(typeof(T), "p"); return Expression.Lambda(Expression.Invoke(f, Expression.Invoke(g, p)), p); } public static Selector GetSelector(Expression> tableSelector, Expression> fieldSelector) { Expression member = fieldSelector.Body; while (member is UnaryExpression) member = ((UnaryExpression)member).Operand; if (!(member is MemberExpression)) throw new ArgumentException("cannot determine field name"); string fieldName = ((MemberExpression)member).Member.Name; return new Selector() { Table = tableSelector.Body.Type, Field = fieldName, Expression = ExpressionTools.CallAfter(fieldSelector, tableSelector), }; } public static readonly List SupportedTypes = new List() { typeof(int), typeof(double), typeof(DateTime), typeof(Guid) }; public static BinaryExpression GetLessThanOrEqualExpression(Expression left, Expression right) { if (SupportedTypes.Contains(typeof(T))) return Expression.LessThanOrEqual(left, right); else if (typeof(T) == typeof(string)) return Expression.LessThanOrEqual( GetStringComparisonExpression(left, right), Expression.Constant(0)); else throw new ArgumentException("Unsupported comparison for types of " + typeof(T)); } public static BinaryExpression GetGreaterOrEqualExpression(Expression left, Expression right) { if (SupportedTypes.Contains(typeof(T))) return Expression.GreaterThanOrEqual(left, right); else if (typeof(T) == typeof(string)) return Expression.GreaterThanOrEqual( GetStringComparisonExpression(left, right), Expression.Constant(0)); else throw new ArgumentException("Unsupported comparison for types of " + typeof(T)); } public static MethodCallExpression GetStringComparisonExpression(Expression left, Expression right) { return Expression.Call(null, String_Compare, left, right); } public static readonly MethodInfo String_Compare = typeof(string).GetMethod("Compare", new[] { typeof(string), typeof(string) }); public static readonly MethodInfo Enumerable_Contains = typeof(Enumerable).GetMethods().Single(mi => mi.Name == "Contains" && mi.GetParameters().Count() == 2); public static readonly MethodInfo Enumerable_Single = typeof(Enumerable).GetMethods().Single(mi => mi.Name == "Single" && mi.GetParameters().Count() == 2); public static readonly MethodInfo Enumerable_Where = (from mi in typeof(Enumerable).GetMethods() where mi.Name == "Where" let p = mi.GetParameters() where p.Count() == 2 let pt = p[1].ParameterType where pt.IsGenericType where pt.GetGenericArguments().Count() == 2 select mi).Single(); public static readonly MethodInfo Enumerable_Cast = typeof(Enumerable).GetMethod("Cast"); public static readonly MethodInfo Enumerable_OrderBy = typeof(Enumerable).GetMethods().Single(mi => mi.Name == "OrderBy" && mi.GetParameters().Count() == 2); public static readonly MethodInfo Enumerable_Count = typeof(Enumerable).GetMethods().Single(mi => mi.Name == "Count" && mi.GetParameters().Count() == 1); } }