Advertisement
LordTerabyte

Custom Linq Extension Methods Updated 08.06.2012

Jun 7th, 2012
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 20.05 KB | None | 0 0
  1. internal static class TypeSystem
  2.     {
  3.         private static Type FindIEnumerable(Type seqType)
  4.         {
  5.             Type type;
  6.             if (seqType == null || seqType == typeof(string) || seqType == typeof(byte[]))
  7.             {
  8.                 return null;
  9.             }
  10.             else
  11.             {
  12.                 if (!seqType.IsArray)
  13.                 {
  14.                     if (seqType.IsGenericType)
  15.                     {
  16.                         Type[] genericArguments = seqType.GetGenericArguments();
  17.                         int num = 0;
  18.                         while (num < (int)genericArguments.Length)
  19.                         {
  20.                             Type type1 = genericArguments[num];
  21.                             Type[] typeArray = new Type[1];
  22.                             typeArray[0] = type1;
  23.                             Type type2 = typeof(IEnumerable<>).MakeGenericType(typeArray);
  24.                             if (!type2.IsAssignableFrom(seqType))
  25.                             {
  26.                                 num++;
  27.                             }
  28.                             else
  29.                             {
  30.                                 type = type2;
  31.                                 return type;
  32.                             }
  33.                         }
  34.                     }
  35.                     Type[] interfaces = seqType.GetInterfaces();
  36.                     if (interfaces != null && (int)interfaces.Length > 0)
  37.                     {
  38.                         Type[] typeArray1 = interfaces;
  39.                         int num1 = 0;
  40.                         while (num1 < (int)typeArray1.Length)
  41.                         {
  42.                             Type type3 = typeArray1[num1];
  43.                             Type type4 = TypeSystem.FindIEnumerable(type3);
  44.                             if (type4 == null)
  45.                             {
  46.                                 num1++;
  47.                             }
  48.                             else
  49.                             {
  50.                                 type = type4;
  51.                                 return type;
  52.                             }
  53.                         }
  54.                     }
  55.                     if (!(seqType.BaseType != null) || !(seqType.BaseType != typeof(object)))
  56.                     {
  57.                         return null;
  58.                     }
  59.                     else
  60.                     {
  61.                         return TypeSystem.FindIEnumerable(seqType.BaseType);
  62.                     }
  63.                 }
  64.                 else
  65.                 {
  66.                     Type[] elementType = new Type[1];
  67.                     elementType[0] = seqType.GetElementType();
  68.                     return typeof(IEnumerable<>).MakeGenericType(elementType);
  69.                 }
  70.             }
  71.         }
  72.  
  73.         internal static Type GetElementType(Type seqType)
  74.         {
  75.             Type type = TypeSystem.FindIEnumerable(seqType);
  76.             if (type != null)
  77.             {
  78.                 return type.GetGenericArguments()[0];
  79.             }
  80.             else
  81.             {
  82.                 return seqType;
  83.             }
  84.         }
  85.     }
  86.  
  87.     [AttributeUsage(AttributeTargets.Method, AllowMultiple= false, Inherited = false)]
  88.     class ExpandableQueryMethodAttribute :
  89.         Attribute
  90.     {
  91.         public ExpandableQueryMethodAttribute()
  92.         {
  93.         }
  94.         public ExpandableQueryMethodAttribute(string expressionId)
  95.         {
  96.             _expressionId = expressionId;
  97.         }
  98.  
  99.         private string _expressionId;
  100.         public LambdaExpression TranslationExpression
  101.         {
  102.             get
  103.             {
  104.                 return _expressionId != null ? QueryMethodTranslationExpressions.GetRegistered(_expressionId) : null;
  105.             }
  106.         }
  107.     }
  108.  
  109.     static class QueryMethodTranslationExpressions
  110.     {
  111.         private static Dictionary<string, LambdaExpression> expressionList = new Dictionary<string, LambdaExpression>();
  112.  
  113.         public static void RegisterExpression<TFunc>(string id, Expression<TFunc> expr)
  114.         {
  115.             expressionList.Add(id, expr);
  116.         }
  117.  
  118.         public static LambdaExpression GetRegistered(string id)
  119.         {
  120.             return expressionList[id];
  121.         }
  122.     }
  123.  
  124.     static class Extensions
  125.     {
  126.         public static IQueryable<T> AsExtendable<T>(this IQueryable<T> source)
  127.         {
  128.             if (source is ExtendableQuery<T>)
  129.             {
  130.                 return (ExtendableQuery<T>)source;
  131.             }
  132.  
  133.             return new ExtendableQueryProvider(source.Provider).CreateQuery<T>(source.Expression);
  134.         }
  135.     }
  136.  
  137.     public class PlaceHolderQueryProvider : IQueryProvider
  138.     {
  139.         public PlaceHolderQueryProvider()
  140.         {
  141.         }
  142.  
  143.         public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
  144.         {
  145.             return new PlaceHolderQuery<TElement>(this, expression);
  146.         }
  147.  
  148.         public IQueryable CreateQuery(Expression expression)
  149.         {
  150.             Type elementType = TypeSystem.GetElementType(expression.Type);
  151.             try
  152.             {
  153.                 return (IQueryable)Activator.CreateInstance(typeof(PlaceHolderQuery<>).MakeGenericType(elementType), new object[] { this, expression });
  154.             }
  155.             catch (System.Reflection.TargetInvocationException tie)
  156.             {
  157.                 throw tie.InnerException;
  158.             }
  159.         }
  160.  
  161.         public TResult Execute<TResult>(Expression expression)
  162.         {
  163.             throw new NotImplementedException();
  164.         }
  165.  
  166.         public object Execute(Expression expression)
  167.         {
  168.             throw new NotImplementedException();
  169.         }
  170.     }
  171.  
  172.     public class PlaceHolderQuery<T> : IQueryable<T>, IOrderedQueryable<T>
  173.     {
  174.        
  175.         private Expression _expression;
  176.         private PlaceHolderQueryProvider _provider;
  177.  
  178.         public PlaceHolderQuery(PlaceHolderQueryProvider provider, Expression expression)
  179.         {
  180.             _provider = provider;
  181.             _expression = expression;
  182.         }
  183.  
  184.         public IEnumerator<T> GetEnumerator()
  185.         {
  186.             throw new NotImplementedException();
  187.         }
  188.  
  189.         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  190.         {
  191.             throw new NotImplementedException();
  192.         }
  193.  
  194.         public Type ElementType
  195.         {
  196.             get
  197.             {
  198.                 return typeof(T);
  199.             }
  200.         }
  201.  
  202.         public Expression Expression
  203.         {
  204.             get
  205.             {
  206.                 return _expression;
  207.             }
  208.         }
  209.  
  210.         public IQueryProvider Provider
  211.         {
  212.             get
  213.             {
  214.                 return _provider;
  215.             }
  216.         }
  217.     }
  218.  
  219.     class ExtendableVisitor : ExpressionVisitor
  220.     {
  221.         class ExpandingVisitor : ExpressionVisitor
  222.         {
  223.             private Dictionary<ParameterExpression, Expression> _substitutionDictionary;
  224.  
  225.             public ExpandingVisitor(Dictionary<ParameterExpression, Expression> subDict)
  226.             {
  227.                 _substitutionDictionary = subDict;
  228.             }
  229.  
  230.             protected override Expression VisitParameter(ParameterExpression node)
  231.             {
  232.                 if (_substitutionDictionary != null && _substitutionDictionary.ContainsKey(node))
  233.                     return _substitutionDictionary[node];
  234.                 else
  235.                     return base.VisitParameter(node);
  236.             }
  237.         }
  238.  
  239.         IQueryProvider _provider;
  240.  
  241.         internal ExtendableVisitor()
  242.         {
  243.             _provider = new PlaceHolderQueryProvider();
  244.         }
  245.  
  246.         protected override Expression VisitMethodCall(MethodCallExpression node)
  247.         {
  248.             ExpandableQueryMethodAttribute attrib = (ExpandableQueryMethodAttribute)node.Method.GetCustomAttributes(typeof(ExpandableQueryMethodAttribute), false).FirstOrDefault();
  249.  
  250.             if (attrib != null && node.Method.IsStatic)
  251.             {
  252.  
  253.                 if (attrib.TranslationExpression != null && attrib.TranslationExpression.Parameters.Count == node.Arguments.Count)
  254.                 {
  255.                     Dictionary<ParameterExpression, Expression> subDict = new Dictionary<ParameterExpression,Expression>();
  256.  
  257.                     for (int i = 0; i < attrib.TranslationExpression.Parameters.Count; i++)
  258.                     {
  259.                         subDict.Add(attrib.TranslationExpression.Parameters[i], node.Arguments[i]);
  260.                     }
  261.  
  262.                     ExpandingVisitor expander = new ExpandingVisitor(subDict);
  263.  
  264.                     Expression exp = expander.Visit(attrib.TranslationExpression.Body);
  265.  
  266.                     return exp;
  267.                 }
  268.                 else if (typeof(IQueryable).IsAssignableFrom(node.Method.ReturnType))
  269.                 {
  270.                     object[] args = new object[node.Arguments.Count];
  271.                     args[0] = _provider.CreateQuery(node.Arguments[0]);
  272.  
  273.                     for (int i = 1; i < node.Arguments.Count; i++)
  274.                     {
  275.                         Expression arg = node.Arguments[i];
  276.                         args[i] = (arg.NodeType == ExpressionType.Constant) ? ((ConstantExpression)arg).Value : arg;
  277.                     }
  278.  
  279.                     Expression exp = ((IQueryable)node.Method.Invoke(null, args)).Expression;
  280.  
  281.                     return exp;
  282.                 }
  283.             }            
  284.  
  285.             return base.VisitMethodCall(node);
  286.         }
  287.     }
  288.  
  289.     static class CompiledExtendableQuery
  290.     {
  291.         public static Func<TContext, TResult>
  292.                    Compile<TContext, TResult>(
  293.            Expression<Func<TContext, TResult>> expr) where TContext : ObjectContext
  294.         {
  295.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  296.         }
  297.  
  298.         public static Func<TContext, TArg0, TResult>
  299.                    Compile<TContext, TArg0, TResult>(
  300.            Expression<Func<TContext, TArg0, TResult>> expr) where TContext : ObjectContext
  301.         {
  302.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  303.         }
  304.  
  305.         public static Func<TContext, TArg0, TArg1, TResult>
  306.                    Compile<TContext, TArg0, TArg1, TResult>
  307.           (Expression<Func<TContext, TArg0, TArg1, TResult>> expr) where TContext : ObjectContext
  308.         {
  309.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  310.         }
  311.  
  312.         public static Func<TContext, TArg0, TArg1, TArg2, TResult>
  313.                    Compile<TContext, TArg0, TArg1, TArg2, TResult>(
  314.            Expression<Func<TContext, TArg0, TArg1, TArg2, TResult>> expr) where TContext : ObjectContext
  315.         {
  316.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  317.         }
  318.  
  319.         public static Func<TContext, TArg0, TArg1, TArg2, TArg3, TResult>
  320.                    Compile<TContext, TArg0, TArg1, TArg2, TArg3, TResult>(
  321.            Expression<Func<TContext, TArg0, TArg1, TArg2, TArg3, TResult>> expr) where TContext : ObjectContext
  322.         {
  323.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  324.         }
  325.  
  326.         public static Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TResult>
  327.                    Compile<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TResult>(
  328.            Expression<Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TResult>> expr) where TContext : ObjectContext
  329.         {
  330.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  331.         }
  332.  
  333.         public static Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TResult>
  334.                    Compile<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TResult>(
  335.            Expression<Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TResult>> expr) where TContext : ObjectContext
  336.         {
  337.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  338.         }
  339.  
  340.         public static Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>
  341.                    Compile<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>(
  342.            Expression<Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>> expr) where TContext : ObjectContext
  343.         {
  344.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  345.         }
  346.  
  347.         public static Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>
  348.                    Compile<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>(
  349.            Expression<Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>> expr) where TContext : ObjectContext
  350.         {
  351.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  352.         }
  353.  
  354.         public static Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>
  355.                    Compile<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>(
  356.            Expression<Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>> expr) where TContext : ObjectContext
  357.         {
  358.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  359.         }
  360.  
  361.         public static Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>
  362.                    Compile<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>(
  363.            Expression<Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>> expr) where TContext : ObjectContext
  364.         {
  365.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  366.         }
  367.  
  368.         public static Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>
  369.                    Compile<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>(
  370.            Expression<Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>> expr) where TContext : ObjectContext
  371.         {
  372.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  373.         }
  374.  
  375.         public static Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult>
  376.                    Compile<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult>(
  377.            Expression<Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult>> expr) where TContext : ObjectContext
  378.         {
  379.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  380.         }
  381.  
  382.         public static Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult>
  383.                    Compile<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult>(
  384.            Expression<Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult>> expr) where TContext : ObjectContext
  385.         {
  386.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  387.         }
  388.  
  389.         public static Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult>
  390.                    Compile<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult>(
  391.            Expression<Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult>> expr) where TContext : ObjectContext
  392.         {
  393.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  394.         }
  395.  
  396.         public static Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult>
  397.                    Compile<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult>(
  398.            Expression<Func<TContext, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult>> expr) where TContext : ObjectContext
  399.         {
  400.             return System.Data.Objects.CompiledQuery.Compile(expr.Update(new ExtendableVisitor().Visit(expr.Body), expr.Parameters));
  401.         }
  402.  
  403.     }
  404.  
  405.     class ExtendableQuery<T> : IQueryable<T>, IOrderedQueryable<T>
  406.     {
  407.         ExtendableQueryProvider _provider;
  408.         Expression _expression;
  409.  
  410.         public ExtendableQuery(ExtendableQueryProvider provider, Expression expression)
  411.         {
  412.             _provider = provider;
  413.             _expression = expression;
  414.         }
  415.  
  416.         public IEnumerator<T> GetEnumerator()
  417.         {
  418.             return _provider.ExecuteQuery<T>(_expression).GetEnumerator();
  419.         }
  420.  
  421.         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  422.         {
  423.             return GetEnumerator();
  424.         }
  425.  
  426.         public Type ElementType
  427.         {
  428.             get {
  429.                 return typeof(T);
  430.             }
  431.         }
  432.  
  433.         public Expression Expression
  434.         {
  435.             get {
  436.                 return _expression;    
  437.             }
  438.         }
  439.  
  440.         public IQueryProvider Provider
  441.         {
  442.             get {
  443.                 return _provider;
  444.             }
  445.         }
  446.  
  447.        
  448.     }
  449.  
  450.     class ExtendableQueryProvider : IQueryProvider
  451.     {
  452.         IQueryProvider _underlyingQueryProvider;
  453.  
  454.         private ExtendableQueryProvider()
  455.         {
  456.         }
  457.  
  458.         internal ExtendableQueryProvider(IQueryProvider underlyingQueryProvider)
  459.         {
  460.             _underlyingQueryProvider = underlyingQueryProvider;
  461.         }
  462.  
  463.         public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
  464.         {
  465.             return new ExtendableQuery<TElement>(this, expression);
  466.         }
  467.  
  468.         public IQueryable CreateQuery(Expression expression)
  469.         {
  470.             Type elementType = TypeSystem.GetElementType(expression.Type);
  471.             try
  472.             {
  473.                 return (IQueryable)Activator.CreateInstance(typeof(ExtendableQuery<>).MakeGenericType(elementType), new object[] { this, expression });
  474.             }
  475.             catch (System.Reflection.TargetInvocationException tie)
  476.             {
  477.                 throw tie.InnerException;
  478.             }
  479.         }
  480.  
  481.         internal IEnumerable<T> ExecuteQuery<T>(Expression expression)
  482.         {
  483.             return _underlyingQueryProvider.CreateQuery<T>(Visit(expression)).AsEnumerable();
  484.         }
  485.  
  486.         public TResult Execute<TResult>(Expression expression)
  487.         {
  488.             return _underlyingQueryProvider.Execute<TResult>(Visit(expression));
  489.         }
  490.  
  491.         public object Execute(Expression expression)
  492.         {
  493.             return _underlyingQueryProvider.Execute(Visit(expression));
  494.         }
  495.  
  496.         private Expression Visit(Expression exp)
  497.         {
  498.             ExtendableVisitor vstr = new ExtendableVisitor();
  499.             Expression visitedExp = vstr.Visit(exp);
  500.  
  501.             return visitedExp;
  502.         }
  503.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement