diff --git a/Extensions/Xtensive.Orm.BulkOperations/Internals/ExpressionExtensions.cs b/Extensions/Xtensive.Orm.BulkOperations/Internals/ExpressionExtensions.cs index 85b080357c..dad34575c7 100644 --- a/Extensions/Xtensive.Orm.BulkOperations/Internals/ExpressionExtensions.cs +++ b/Extensions/Xtensive.Orm.BulkOperations/Internals/ExpressionExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Linq.Expressions; +using Xtensive.Linq; using Xtensive.Reflection; namespace Xtensive.Orm.BulkOperations @@ -23,7 +24,7 @@ public static bool IsContainsQuery(this Expression expression) internal static object Invoke(this Expression expression) { - return Expression.Lambda(typeof (Func<>).MakeGenericType(expression.Type), expression).Compile().DynamicInvoke(); + return FastExpression.Lambda(typeof (Func<>).MakeGenericType(expression.Type), expression).Compile().DynamicInvoke(); } internal static Expression Visit(this Expression exp, Func visitor) where T : Expression diff --git a/Extensions/Xtensive.Orm.BulkOperations/Internals/SetOperation.cs b/Extensions/Xtensive.Orm.BulkOperations/Internals/SetOperation.cs index bdf7edae10..4b260d324a 100644 --- a/Extensions/Xtensive.Orm.BulkOperations/Internals/SetOperation.cs +++ b/Extensions/Xtensive.Orm.BulkOperations/Internals/SetOperation.cs @@ -7,6 +7,7 @@ using Xtensive.Sql; using Xtensive.Sql.Dml; using Xtensive.Core; +using Xtensive.Linq; namespace Xtensive.Orm.BulkOperations { @@ -139,7 +140,7 @@ private void AddConstantValue(AddValueContext addContext) { SqlTableColumn column = SqlDml.TableColumn(addContext.Statement.Table, addContext.Field.Column.Name); SqlExpression value; - object constant = Expression.Lambda(addContext.Lambda.Body, null).Compile().DynamicInvoke(); + object constant = FastExpression.Lambda(addContext.Lambda.Body, null).Compile().DynamicInvoke(); if (constant==null) value = SqlDml.Null; else { @@ -199,7 +200,7 @@ private void AddEntityValue(AddValueContext addContext) i++; ParameterExpression p = Expression.Parameter(info.UnderlyingType); LambdaExpression lambda = - Expression.Lambda( + FastExpression.Lambda( typeof (Func<,>).MakeGenericType(info.UnderlyingType, field.ValueType), Expression.MakeMemberAccess(p, field.UnderlyingProperty), p); @@ -215,7 +216,7 @@ private void AddEntityValue(AddValueContext addContext) } } i = -1; - var entity = (IEntity) Expression.Lambda(addContext.Lambda.Body, null).Compile().DynamicInvoke(); + var entity = (IEntity) FastExpression.Lambda(addContext.Lambda.Body, null).Compile().DynamicInvoke(); foreach (ColumnInfo column in addContext.Field.Columns) { i++; SqlExpression value; @@ -238,7 +239,7 @@ public void AddValues() var addContext = new AddValueContext { Descriptor = descriptor, Lambda = - Expression.Lambda( + FastExpression.Lambda( typeof (Func<,>).MakeGenericType(typeof (T), descriptor.Expression.Type), descriptor.Expression, descriptor.Parameter), diff --git a/Extensions/Xtensive.Orm.Security/SecureQueryRootBuilder.cs b/Extensions/Xtensive.Orm.Security/SecureQueryRootBuilder.cs index ee3428808e..9fe636d2d7 100644 --- a/Extensions/Xtensive.Orm.Security/SecureQueryRootBuilder.cs +++ b/Extensions/Xtensive.Orm.Security/SecureQueryRootBuilder.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using Xtensive.Linq; using Xtensive.Orm; namespace Xtensive.Orm.Security @@ -54,7 +55,7 @@ private IQueryable GetSecureQuery(ImpersonationContext context) where T: c continue; } var p = Expression.Parameter(queryType, "p"); - var where = (Expression>) Expression.Lambda(Expression.Not(Expression.TypeIs(p, permissionType)), p); + var where = (Expression>) FastExpression.Lambda(Expression.Not(Expression.TypeIs(p, permissionType)), p); candidates.Add(InsecureQuery.All().Where(where).Concat(permission.Query(context, InsecureQuery).OfType())); } // Query && Permission diff --git a/Orm/Xtensive.Orm.Tests.Core/Linq/LambdaExpressionFactoryTests.cs b/Orm/Xtensive.Orm.Tests.Core/Linq/LambdaExpressionFactoryTests.cs new file mode 100644 index 0000000000..5404830387 --- /dev/null +++ b/Orm/Xtensive.Orm.Tests.Core/Linq/LambdaExpressionFactoryTests.cs @@ -0,0 +1,54 @@ +// Copyright (C) 2020 Xtensive LLC. +// This code is distributed under MIT license terms. +// See the License.txt file in the project root for more information. + +using System; +using System.Linq.Expressions; +using NUnit.Framework; +using Xtensive.Core; +using Xtensive.Linq; + +namespace Xtensive.Orm.Tests.Core.Linq +{ + [TestFixture] + public class LambdaExpressionFactoryTests + { + private readonly Type delegateType = typeof(Func); + private readonly Expression> plusOne = i => i + 1; + + [Test] + public void ShouldUseFastFactory() => Assert.That(LambdaExpressionFactory.CanUseFastFactory()); + + [Test] + public void ShouldCreateFactoryFast() + { + var lambda = (Func) LambdaExpressionFactory + .CreateFactoryFast(delegateType) + .Invoke(plusOne.Body, plusOne.Parameters.ToArray()) + .Compile(); + + Assert.That(lambda.Invoke(1), Is.EqualTo(2)); + } + + [Test] + public void ShouldCreateFactorySlow() + { + var lambda = (Func) LambdaExpressionFactory.Instance + .CreateFactorySlow(delegateType) + .Invoke(plusOne.Body, plusOne.Parameters.ToArray()) + .Compile(); + + Assert.That(lambda.Invoke(1), Is.EqualTo(2)); + } + + [Test] + public void ShouldCreateLambda() + { + var lambda = (Func) LambdaExpressionFactory.Instance + .CreateLambda(delegateType, plusOne.Body, plusOne.Parameters.ToArray()) + .Compile(); + + Assert.That(lambda.Invoke(1), Is.EqualTo(2)); + } + } +} \ No newline at end of file diff --git a/Orm/Xtensive.Orm/Core/Extensions/ExpressionExtensions.cs b/Orm/Xtensive.Orm/Core/Extensions/ExpressionExtensions.cs index 5b9620f4c4..d25d43b511 100644 --- a/Orm/Xtensive.Orm/Core/Extensions/ExpressionExtensions.cs +++ b/Orm/Xtensive.Orm/Core/Extensions/ExpressionExtensions.cs @@ -242,7 +242,7 @@ public static LambdaExpression StripQuotes(this Expression expression) if (!typeof (LambdaExpression).IsAssignableFrom(expression.Type)) throw new InvalidOperationException(string.Format("Unable to process expression '{0}'", expression)); var typeAs = Expression.TypeAs(expression, typeof (LambdaExpression)); - return Expression.Lambda>(typeAs).CachingCompile()(); + return FastExpression.Lambda>(typeAs).CachingCompile()(); } return lambda; } diff --git a/Orm/Xtensive.Orm/Linq/ExpressionVisitor.cs b/Orm/Xtensive.Orm/Linq/ExpressionVisitor.cs index 0adbc871d4..72f4d12d86 100644 --- a/Orm/Xtensive.Orm/Linq/ExpressionVisitor.cs +++ b/Orm/Xtensive.Orm/Linq/ExpressionVisitor.cs @@ -150,7 +150,7 @@ protected override Expression VisitLambda(LambdaExpression l) { Expression body = Visit(l.Body); if (body!=l.Body) - return Expression.Lambda(l.Type, body, l.Parameters); + return FastExpression.Lambda(l.Type, body, l.Parameters); return l; } diff --git a/Orm/Xtensive.Orm/Linq/FastExpression.cs b/Orm/Xtensive.Orm/Linq/FastExpression.cs index 8b9b0b89f9..b303e6cdbd 100644 --- a/Orm/Xtensive.Orm/Linq/FastExpression.cs +++ b/Orm/Xtensive.Orm/Linq/FastExpression.cs @@ -29,6 +29,18 @@ public static LambdaExpression Lambda(Type delegateType, Expression body, params return LambdaExpressionFactory.Instance.CreateLambda(delegateType, body, parameters); } + /// + /// Generates faster than . + /// + /// A type that represents a delegate type. + /// The body of lambda expression. + /// The parameters of lambda expression. + /// Constructed lambda expression. + public static Expression Lambda(Expression body, params ParameterExpression[] parameters) + { + return (Expression) LambdaExpressionFactory.Instance.CreateLambda(typeof(TDelegate), body, parameters); + } + /// /// Generates faster than . /// diff --git a/Orm/Xtensive.Orm/Linq/Internals/LambdaExpressionFactory.cs b/Orm/Xtensive.Orm/Linq/Internals/LambdaExpressionFactory.cs index c5708d3fe3..b02e9590b0 100644 --- a/Orm/Xtensive.Orm/Linq/Internals/LambdaExpressionFactory.cs +++ b/Orm/Xtensive.Orm/Linq/Internals/LambdaExpressionFactory.cs @@ -13,15 +13,33 @@ using Xtensive.Reflection; using Factory = System.Func< - System.Linq.Expressions.Expression, - System.Collections.Generic.IEnumerable, - System.Linq.Expressions.LambdaExpression + System.Linq.Expressions.Expression, + System.Linq.Expressions.ParameterExpression[], + System.Linq.Expressions.LambdaExpression + >; + +using SlowFactory = System.Func< + System.Linq.Expressions.Expression, + System.Collections.Generic.IEnumerable, + System.Linq.Expressions.LambdaExpression + >; + +using FastFactory = System.Func< + System.Linq.Expressions.Expression, + string, + bool, + System.Collections.Generic.IReadOnlyList, + System.Linq.Expressions.LambdaExpression >; namespace Xtensive.Linq { internal sealed class LambdaExpressionFactory { + private static readonly Type[] internalFactorySignature = new[] { + typeof(Expression), typeof(string), typeof(bool), typeof(IReadOnlyList) + }; + private static readonly object _lock = new object(); private static volatile LambdaExpressionFactory instance; @@ -32,16 +50,17 @@ public static LambdaExpressionFactory Instance { return instance; } } - - private readonly MethodInfo factoryMethod; + private readonly ThreadSafeDictionary cache; + private readonly Func createHandler; + private readonly MethodInfo slowFactoryMethod; public LambdaExpression CreateLambda(Type delegateType, Expression body, ParameterExpression[] parameters) { - var factory = cache.GetValue(delegateType, (_delegateType, _this) => _this.CreateFactory(_delegateType), this); + var factory = cache.GetValue(delegateType, createHandler); return factory.Invoke(body, parameters); } - + public LambdaExpression CreateLambda(Expression body, ParameterExpression[] parameters) { var delegateType = DelegateHelper.MakeDelegateType(body.Type, parameters.Select(p => p.Type)); @@ -49,10 +68,36 @@ public LambdaExpression CreateLambda(Expression body, ParameterExpression[] para } #region Private / internal methods - - private Factory CreateFactory(Type delegateType) + + internal Factory CreateFactorySlow(Type delegateType) + { + var factory = (SlowFactory) Delegate.CreateDelegate( + typeof(SlowFactory), slowFactoryMethod.MakeGenericMethod(delegateType)); + + return (body, parameters) => factory.Invoke(body, parameters); + } + + internal static Factory CreateFactoryFast(Type delegateType) { - return (Factory) Delegate.CreateDelegate(typeof (Factory), factoryMethod.MakeGenericMethod(delegateType)); + var method = typeof(Expression<>).MakeGenericType(delegateType).GetMethod( + "Create", BindingFlags.Static | BindingFlags.NonPublic, null, internalFactorySignature, null); + + if (method == null) { + return null; + } + + var factory = (FastFactory) Delegate.CreateDelegate(typeof(FastFactory), null, method); + return (body, parameters) => factory.Invoke(body, null, false, parameters); + } + + internal static bool CanUseFastFactory() + { + try { + return CreateFactoryFast(typeof(Func)) != null; + } + catch { + return false; + } } #endregion @@ -62,11 +107,13 @@ private Factory CreateFactory(Type delegateType) private LambdaExpressionFactory() { cache = ThreadSafeDictionary.Create(new object()); - factoryMethod = typeof (Expression).GetMethods() - .Where(m => m.IsGenericMethod - && m.Name == "Lambda" - && m.GetParameters()[1].ParameterType == typeof(IEnumerable)) - .Single(); + + slowFactoryMethod = typeof(Expression).GetMethods().Single(m => + m.IsGenericMethod && + m.Name == "Lambda" && + m.GetParameters()[1].ParameterType == typeof(IEnumerable)); + + createHandler = CanUseFastFactory() ? (Func) CreateFactoryFast : CreateFactorySlow; } } } \ No newline at end of file diff --git a/Orm/Xtensive.Orm/Orm/Building/Builders/PartialIndexFilterBuilder.cs b/Orm/Xtensive.Orm/Orm/Building/Builders/PartialIndexFilterBuilder.cs index 59650a60fa..edd22d8961 100644 --- a/Orm/Xtensive.Orm/Orm/Building/Builders/PartialIndexFilterBuilder.cs +++ b/Orm/Xtensive.Orm/Orm/Building/Builders/PartialIndexFilterBuilder.cs @@ -10,6 +10,7 @@ using System.Linq.Expressions; using System.Reflection; using Xtensive.Core; +using Xtensive.Linq; using Xtensive.Orm; using Xtensive.Reflection; using Xtensive.Orm.Linq; @@ -37,7 +38,7 @@ public static void BuildFilter(IndexInfo index) var builder = new PartialIndexFilterBuilder(index, parameter); var body = builder.Visit(index.FilterExpression.Body); var filter = new PartialIndexFilterInfo { - Expression = Expression.Lambda(body, parameter), + Expression = FastExpression.Lambda(body, parameter), Fields = builder.usedFields, }; index.Filter = filter; diff --git a/Orm/Xtensive.Orm/Orm/Linq/ExpressionEvaluator.cs b/Orm/Xtensive.Orm/Orm/Linq/ExpressionEvaluator.cs index 6a64673b9a..ce8ca7190f 100644 --- a/Orm/Xtensive.Orm/Orm/Linq/ExpressionEvaluator.cs +++ b/Orm/Xtensive.Orm/Orm/Linq/ExpressionEvaluator.cs @@ -10,6 +10,7 @@ using System.Linq.Expressions; using System.Reflection; using Xtensive.Core; +using Xtensive.Linq; using Xtensive.Orm.Rse; using Xtensive.Reflection; using ExpressionVisitor = Xtensive.Linq.ExpressionVisitor; @@ -50,7 +51,7 @@ public static ConstantExpression Evaluate(Expression e) Type type = e.Type; if (type.IsValueType) e = Expression.Convert(e, typeof (object)); - var lambda = Expression.Lambda>(e); + var lambda = FastExpression.Lambda>(e); var func = lambda.CachingCompile(); return Expression.Constant(func(), type); } diff --git a/Orm/Xtensive.Orm/Orm/Linq/ItemToTupleConverter{TItem}.cs b/Orm/Xtensive.Orm/Orm/Linq/ItemToTupleConverter{TItem}.cs index 645eb18441..4d26558e3f 100644 --- a/Orm/Xtensive.Orm/Orm/Linq/ItemToTupleConverter{TItem}.cs +++ b/Orm/Xtensive.Orm/Orm/Linq/ItemToTupleConverter{TItem}.cs @@ -12,6 +12,7 @@ using System.Reflection; using Xtensive.Collections; using Xtensive.Core; +using Xtensive.Linq; using Xtensive.Reflection; using Xtensive.Tuples; using Tuple = Xtensive.Tuples.Tuple; @@ -62,7 +63,7 @@ public override Expression>> GetEnumerable() var call = Expression.Call(Expression.Constant(enumerableFunc.Target), enumerableFunc.Method); MethodInfo selectMethod = WellKnownMembers.Enumerable.Select.MakeGenericMethod(typeof (TItem), typeof (Tuple)); var select = Expression.Call(selectMethod, call, Expression.Constant(converter)); - return Expression.Lambda>>(select); + return FastExpression.Lambda>>(select); } diff --git a/Orm/Xtensive.Orm/Orm/Linq/ParameterExtractor.cs b/Orm/Xtensive.Orm/Orm/Linq/ParameterExtractor.cs index 6f31110a17..d19c302377 100644 --- a/Orm/Xtensive.Orm/Orm/Linq/ParameterExtractor.cs +++ b/Orm/Xtensive.Orm/Orm/Linq/ParameterExtractor.cs @@ -6,6 +6,7 @@ using System; using System.Linq.Expressions; +using Xtensive.Linq; using ExpressionVisitor = Xtensive.Linq.ExpressionVisitor; namespace Xtensive.Orm.Linq @@ -45,7 +46,7 @@ public Expression> ExtractParameter(Expression expression) Type type = expression.Type; if (type.IsValueType) expression = Expression.Convert(expression, typeof (T)); - var lambda = Expression.Lambda>(expression); + var lambda = FastExpression.Lambda>(expression); return lambda; } diff --git a/Orm/Xtensive.Orm/Orm/Linq/QueryHelper.cs b/Orm/Xtensive.Orm/Orm/Linq/QueryHelper.cs index 2cee940d52..34cda1331a 100644 --- a/Orm/Xtensive.Orm/Orm/Linq/QueryHelper.cs +++ b/Orm/Xtensive.Orm/Orm/Linq/QueryHelper.cs @@ -53,7 +53,7 @@ public static Expression> BuildFilterLambda(int startIndex, IR filterExpression = Expression.And(filterExpression, Expression.Equal(tupleParameterFieldAccess, keyParameterFieldAccess)); } - return Expression.Lambda>(filterExpression, tupleParameter); + return FastExpression.Lambda>(filterExpression, tupleParameter); } private static Expression CreateEntityQuery(Type elementType) diff --git a/Orm/Xtensive.Orm/Orm/Linq/Rewriters/SelectManySelectorRewriter.cs b/Orm/Xtensive.Orm/Orm/Linq/Rewriters/SelectManySelectorRewriter.cs index 31a18cf903..08c401804a 100644 --- a/Orm/Xtensive.Orm/Orm/Linq/Rewriters/SelectManySelectorRewriter.cs +++ b/Orm/Xtensive.Orm/Orm/Linq/Rewriters/SelectManySelectorRewriter.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Linq.Expressions; +using Xtensive.Linq; using ExpressionVisitor = Xtensive.Linq.ExpressionVisitor; namespace Xtensive.Orm.Linq.Rewriters @@ -42,7 +43,7 @@ public static bool TryRewrite(LambdaExpression resultSelector, result = null; return false; } - result = Expression.Lambda(body, parameters); + result = FastExpression.Lambda(body, parameters); return true; } diff --git a/Orm/Xtensive.Orm/Orm/Linq/Translator.Expressions.cs b/Orm/Xtensive.Orm/Orm/Linq/Translator.Expressions.cs index b3bb51eac3..1f3856346e 100644 --- a/Orm/Xtensive.Orm/Orm/Linq/Translator.Expressions.cs +++ b/Orm/Xtensive.Orm/Orm/Linq/Translator.Expressions.cs @@ -279,7 +279,7 @@ protected override Expression VisitMemberAccess(MemberExpression ma) if (context.Evaluator.CanBeEvaluated(ma) && context.ParameterExtractor.IsParameter(ma)) { if (typeof (IQueryable).IsAssignableFrom(ma.Type)) { - Func lambda = Expression.Lambda>(ma).CachingCompile(); + Func lambda = FastExpression.Lambda>(ma).CachingCompile(); IQueryable rootPoint = lambda(); if (rootPoint!=null) return base.Visit(rootPoint.Expression); @@ -288,7 +288,7 @@ protected override Expression VisitMemberAccess(MemberExpression ma) } if (ma.Expression==null) { if (typeof (IQueryable).IsAssignableFrom(ma.Type)) { - var lambda = Expression.Lambda>(ma).CachingCompile(); + var lambda = FastExpression.Lambda>(ma).CachingCompile(); var rootPoint = lambda(); if (rootPoint!=null) return VisitSequence(rootPoint.Expression); @@ -297,7 +297,7 @@ protected override Expression VisitMemberAccess(MemberExpression ma) else if (ma.Expression.NodeType==ExpressionType.Constant) { var rfi = ma.Member as FieldInfo; if (rfi!=null && (rfi.FieldType.IsGenericType && typeof (IQueryable).IsAssignableFrom(rfi.FieldType))) { - var lambda = Expression.Lambda>(ma).CachingCompile(); + var lambda = FastExpression.Lambda>(ma).CachingCompile(); var rootPoint = lambda(); if (rootPoint!=null) return VisitSequence(rootPoint.Expression); @@ -519,7 +519,7 @@ private Expression ConstructContainsTableQueryRoot(Type elementType, System.Coll var func = ((Expression>) rawSearchCriteria).Compile(); var conditionCompiler = context.Domain.Handler.GetSearchConditionCompiler(); func.Invoke(SearchConditionNodeFactory.CreateConditonRoot()).AcceptVisitor(conditionCompiler); - var preparedSearchCriteria = Expression.Lambda>(Expression.Constant(conditionCompiler.CurrentOutput)); + var preparedSearchCriteria = FastExpression.Lambda>(Expression.Constant(conditionCompiler.CurrentOutput)); if (QueryCachingScope.Current==null) compiledParameter = ((Expression>) preparedSearchCriteria).CachingCompile(); diff --git a/Orm/Xtensive.Orm/Orm/Linq/Translator.Materialization.cs b/Orm/Xtensive.Orm/Orm/Linq/Translator.Materialization.cs index 7fd3fd1f66..a07a842365 100644 --- a/Orm/Xtensive.Orm/Orm/Linq/Translator.Materialization.cs +++ b/Orm/Xtensive.Orm/Orm/Linq/Translator.Materialization.cs @@ -144,7 +144,7 @@ private Func, Session, Dictionary, Tuple>, P ? body : Expression.Convert(body, typeof (TResult)); - var projectorExpression = Expression.Lambda, Session, Dictionary, Tuple>, ParameterContext, TResult>>(body, rs, session, tupleParameterBindings, parameterContext); + var projectorExpression = FastExpression.Lambda, Session, Dictionary, Tuple>, ParameterContext, TResult>>(body, rs, session, tupleParameterBindings, parameterContext); return projectorExpression.CachingCompile(); } diff --git a/Orm/Xtensive.Orm/Orm/Linq/Translator.Queryable.cs b/Orm/Xtensive.Orm/Orm/Linq/Translator.Queryable.cs index fa8732f5db..fdfafb5d0d 100644 --- a/Orm/Xtensive.Orm/Orm/Linq/Translator.Queryable.cs +++ b/Orm/Xtensive.Orm/Orm/Linq/Translator.Queryable.cs @@ -443,7 +443,7 @@ private Expression VisitElementAt(Expression source, Expression index, bool isRo compiledParameter = elementAtIndex.CachingCompile(); var skipComparison = Expression.LessThan(elementAtIndex.Body, Expression.Constant(0)); var condition = Expression.Condition(skipComparison, Expression.Constant(0), Expression.Constant(1)); - var takeParameter = Expression.Lambda>(condition); + var takeParameter = FastExpression.Lambda>(condition); rs = projection.ItemProjector.DataSource.Skip(compiledParameter).Take(takeParameter.CachingCompile()); } else { @@ -705,7 +705,7 @@ private Pair VisitAggregateSource( var lambdaType = sourceProjection.ItemProjector.Item.Type; EnsureAggregateIsPossible(lambdaType, aggregateType, visitedExpression); var paramExpression = Expression.Parameter(lambdaType, "arg"); - aggregateParameter = Expression.Lambda(paramExpression, paramExpression); + aggregateParameter = FastExpression.Lambda(paramExpression, paramExpression); } } @@ -1534,11 +1534,11 @@ private Expression VisitContainsAny(Expression setA, Expression setB, bool isRoo var containsMethod = WellKnownMembers.Enumerable.Contains.MakeGenericMethod(elementType); if (setAIsQuery) { - var lambda = Expression.Lambda(Expression.Call(containsMethod, setB, parameter), parameter); + var lambda = FastExpression.Lambda(Expression.Call(containsMethod, setB, parameter), parameter); return VisitAny(setA, lambda, isRoot); } else { - var lambda = Expression.Lambda(Expression.Call(containsMethod, setA, parameter), parameter); + var lambda = FastExpression.Lambda(Expression.Call(containsMethod, setA, parameter), parameter); return VisitAny(setB, lambda, isRoot); } } @@ -1551,7 +1551,7 @@ private Expression VisitContainsAll(Expression setA, Expression setB, bool isRoo var parameter = Expression.Parameter(elementType, "a"); var containsMethod = WellKnownMembers.Enumerable.Contains.MakeGenericMethod(elementType); - var lambda = Expression.Lambda(Expression.Call(containsMethod, setA, parameter), parameter); + var lambda = FastExpression.Lambda(Expression.Call(containsMethod, setA, parameter), parameter); return VisitAll(setB, lambda, isRoot); } @@ -1564,11 +1564,11 @@ private Expression VisitContainsNone(Expression setA, Expression setB, bool isRo var parameter = Expression.Parameter(elementType, "a"); var containsMethod = WellKnownMembers.Enumerable.Contains.MakeGenericMethod(elementType); if (setAIsQuery) { - var lambda = Expression.Lambda(Expression.Not(Expression.Call(containsMethod, setB, parameter)), parameter); + var lambda = FastExpression.Lambda(Expression.Not(Expression.Call(containsMethod, setB, parameter)), parameter); return VisitAll(setA, lambda, isRoot); } else { - var lambda = Expression.Lambda(Expression.Not(Expression.Call(containsMethod, setA, parameter)), parameter); + var lambda = FastExpression.Lambda(Expression.Not(Expression.Call(containsMethod, setA, parameter)), parameter); return VisitAll(setB, lambda, isRoot); } } diff --git a/Orm/Xtensive.Orm/Orm/Rse/Transformation/Internals/ApplyFilterRewriter.cs b/Orm/Xtensive.Orm/Orm/Rse/Transformation/Internals/ApplyFilterRewriter.cs index 243e808c17..d761a28a76 100644 --- a/Orm/Xtensive.Orm/Orm/Rse/Transformation/Internals/ApplyFilterRewriter.cs +++ b/Orm/Xtensive.Orm/Orm/Rse/Transformation/Internals/ApplyFilterRewriter.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Linq.Expressions; using Xtensive.Core; +using Xtensive.Linq; using Tuple = Xtensive.Tuples.Tuple; using ExpressionVisitor = Xtensive.Linq.ExpressionVisitor; @@ -25,7 +26,7 @@ public Expression> Rewrite(Expression Initialize(predicate, predicateColumns, currentColumns); leftTupleParameter = Expression.Parameter(typeof (Tuple), "leftTuple"); var visited = Visit(predicate.Body); - return (Expression>) Expression + return (Expression>) FastExpression .Lambda(visited, leftTupleParameter, predicate.Parameters[0]); } diff --git a/Orm/Xtensive.Orm/Orm/Rse/Transformation/Internals/CollectorHelper.cs b/Orm/Xtensive.Orm/Orm/Rse/Transformation/Internals/CollectorHelper.cs index 862f3aa837..f9aa182541 100644 --- a/Orm/Xtensive.Orm/Orm/Rse/Transformation/Internals/CollectorHelper.cs +++ b/Orm/Xtensive.Orm/Orm/Rse/Transformation/Internals/CollectorHelper.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Linq.Expressions; using Xtensive.Core; +using Xtensive.Linq; using Xtensive.Orm.Rse.Providers; using Xtensive.Tuples; using Tuple = Xtensive.Tuples.Tuple; @@ -26,7 +27,7 @@ public Expression> CreatePredicatesConjunction( var newParameter = newPredicate.Parameters[0]; var result = (Expression>) parameterRewriter .Replace(oldPredicate, oldParameter, newParameter); - return (Expression>) Expression.Lambda(Expression + return (Expression>) FastExpression.Lambda(Expression .AndAlso(result.Body, newPredicate.Body),newParameter); } @@ -41,7 +42,7 @@ public Expression> CreatePredicatesConjunction( var newParameter1 = newPredicate.Parameters[1]; result = (Expression>) parameterRewriter .Replace(result, oldParameter1, newParameter1); - return (Expression>) Expression.Lambda(Expression + return (Expression>) FastExpression.Lambda(Expression .AndAlso(result.Body, newPredicate.Body), newParameter0, newParameter1); } diff --git a/Orm/Xtensive.Orm/Orm/Rse/Transformation/RedundantColumnRemover.cs b/Orm/Xtensive.Orm/Orm/Rse/Transformation/RedundantColumnRemover.cs index 455eea75a0..879f0e26e6 100644 --- a/Orm/Xtensive.Orm/Orm/Rse/Transformation/RedundantColumnRemover.cs +++ b/Orm/Xtensive.Orm/Orm/Rse/Transformation/RedundantColumnRemover.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Linq.Expressions; using Xtensive.Core; +using Xtensive.Linq; using Xtensive.Orm.Rse.Providers; using Tuple = Xtensive.Tuples.Tuple; using Xtensive.Tuples.Transform; @@ -46,7 +47,7 @@ private static Expression>> RemapRawProviderSource(Expre Func selector = tuple => mappingTransform.Apply(TupleTransformType.Auto, tuple); var newExpression = Expression.Call(selectMethodInfo, source.Body, Expression.Constant(selector)); - return (Expression>>)Expression.Lambda(newExpression); + return (Expression>>)FastExpression.Lambda(newExpression); } // Constructors diff --git a/Orm/Xtensive.Orm/Orm/Rse/TupleExpressionExtensions.cs b/Orm/Xtensive.Orm/Orm/Rse/TupleExpressionExtensions.cs index 812aec4c08..3d9bd30e5c 100644 --- a/Orm/Xtensive.Orm/Orm/Rse/TupleExpressionExtensions.cs +++ b/Orm/Xtensive.Orm/Orm/Rse/TupleExpressionExtensions.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Linq.Expressions; using Xtensive.Core; +using Xtensive.Linq; using Tuple = Xtensive.Tuples.Tuple; namespace Xtensive.Orm.Rse @@ -144,7 +145,7 @@ private static T Evaluate(Expression expression) { if (expression.NodeType==ExpressionType.Constant) return (T) ((ConstantExpression) expression).Value; - return Expression.Lambda>(expression).CachingCompile().Invoke(); + return FastExpression.Lambda>(expression).CachingCompile().Invoke(); } } } \ No newline at end of file