|
From: <ste...@us...> - 2010-02-26 20:47:16
|
Revision: 4948
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4948&view=rev
Author: steverstrong
Date: 2010-02-26 20:47:09 +0000 (Fri, 26 Feb 2010)
Log Message:
-----------
Eager loading support in Linq provider
Modified Paths:
--------------
trunk/nhibernate/lib/net/3.5/Remotion.Data.Linq.dll
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs
trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs
trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs
trunk/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/Nominator.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/IResultOperatorProcessor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAggregate.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAll.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAny.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessClientSideSelect.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFirst.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFirstOrSingleBase.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessGroupBy.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessNonAggregatingGroupBy.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessResultOperatorReturn.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSingle.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSkip.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessTake.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ResultOperatorMap.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ResultOperatorProcessor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ResultOperatorProcessorBase.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/SelectClauseVisitor.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Customer.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Employee.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Order.cs
trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Linq/EagerFetchingExtensionMethods.cs
trunk/nhibernate/src/NHibernate/Linq/Expressions/AggregateExpressionNode.cs
trunk/nhibernate/src/NHibernate/Linq/IntermediateHqlTree.cs
trunk/nhibernate/src/NHibernate/Linq/NhRelinqQueryParser.cs
trunk/nhibernate/src/NHibernate/Linq/ResultOperators/AggregateResultOperator.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/NameUnNamedParameters.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/QuerySourceLocator.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFetch.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFetchMany.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFetchOne.cs
trunk/nhibernate/src/NHibernate.Test/Linq/EagerLoadTests.cs
Property Changed:
----------------
trunk/nhibernate/src/
trunk/nhibernate/src/NHibernate/
Modified: trunk/nhibernate/lib/net/3.5/Remotion.Data.Linq.dll
===================================================================
(Binary files differ)
Property changes on: trunk/nhibernate/src
___________________________________________________________________
Modified: svn:ignore
- *.suo
CloverSrc
_ReSharper*
*.resharperoptions
*.resharper.user
CloverBuild
Ankh.Load
*.resharper
ConsoleTest
_UpgradeReport_Files
NHibernate.userprefs
NHibernate.usertasks
UpgradeLog.XML
UpgradeLog2.XML
UpgradeLog3.XML
UpgradeLog4.XML
UpgradeLog5.XML
UpgradeLog6.XML
UpgradeLog7.XML
UpgradeLog8.XML
UpgradeLog9.XML
NHibernate.sln.proj
NHibernate.sln.AssemblySurfaceCache.user
NHibernate.sln.cache
.git
+ *.suo
CloverSrc
_ReSharper*
*.resharperoptions
*.resharper.user
CloverBuild
Ankh.Load
*.resharper
ConsoleTest
_UpgradeReport_Files
NHibernate.userprefs
NHibernate.usertasks
UpgradeLog.XML
UpgradeLog2.XML
UpgradeLog3.XML
UpgradeLog4.XML
UpgradeLog5.XML
UpgradeLog6.XML
UpgradeLog7.XML
UpgradeLog8.XML
UpgradeLog9.XML
NHibernate.sln.proj
NHibernate.sln.AssemblySurfaceCache.user
NHibernate.sln.cache
.git
.gitignore
NHibernate.5.0.ReSharper.user
Property changes on: trunk/nhibernate/src/NHibernate
___________________________________________________________________
Modified: svn:ignore
- obj
.#*
*.user
*.xsx
AssemblyInfo.cs
*.aps
*.eto
[Bb]in
[Dd]ebug
[Rr]elease
*resharper*
_ReSharper.NHibernate
NHibernate.pidb
+ obj
.#*
*.user
*.xsx
AssemblyInfo.cs
*.aps
*.eto
[Bb]in
[Dd]ebug
[Rr]elease
*resharper*
_ReSharper.NHibernate
NHibernate.pidb
NHibernate.suo
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -391,9 +391,19 @@
return new HqlIn(_factory, itemExpression, source);
}
- public HqlTreeNode LeftJoin(HqlExpression expression, HqlAlias @alias)
+ public HqlLeftJoin LeftJoin(HqlExpression expression, HqlAlias @alias)
{
return new HqlLeftJoin(_factory, expression, @alias);
}
+
+ public HqlFetchJoin FetchJoin(HqlExpression expression, HqlAlias @alias)
+ {
+ return new HqlFetchJoin(_factory, expression, @alias);
+ }
+
+ public HqlLeftFetchJoin LeftFetchJoin(HqlExpression expression, HqlAlias @alias)
+ {
+ return new HqlLeftFetchJoin(_factory, expression, @alias);
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -674,6 +674,22 @@
}
}
+ public class HqlFetchJoin : HqlTreeNode
+ {
+ public HqlFetchJoin(IASTFactory factory, HqlExpression expression, HqlAlias @alias)
+ : base(HqlSqlWalker.JOIN, "join", factory, new HqlFetch(factory), expression, @alias)
+ {
+ }
+ }
+
+ public class HqlLeftFetchJoin : HqlTreeNode
+ {
+ public HqlLeftFetchJoin(IASTFactory factory, HqlExpression expression, HqlAlias @alias)
+ : base(HqlSqlWalker.JOIN, "join", factory, new HqlLeft(factory), new HqlFetch(factory), expression, @alias)
+ {
+ }
+ }
+
public class HqlFetch : HqlTreeNode
{
public HqlFetch(IASTFactory factory) : base(HqlSqlWalker.FETCH, "fetch", factory)
Added: trunk/nhibernate/src/NHibernate/Linq/EagerFetchingExtensionMethods.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/EagerFetchingExtensionMethods.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/EagerFetchingExtensionMethods.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using Remotion.Data.Linq.EagerFetching;
+using Remotion.Data.Linq.Utilities;
+
+namespace NHibernate.Linq
+{
+ public static class EagerFetchingExtensionMethods
+ {
+ public static FluentFetchRequest<TOriginating, TRelated> Fetch<TOriginating, TRelated>(
+ this IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector)
+ {
+ ArgumentUtility.CheckNotNull("query", query);
+ ArgumentUtility.CheckNotNull("relatedObjectSelector", relatedObjectSelector);
+
+ var methodInfo = ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TOriginating), typeof(TRelated));
+ return CreateFluentFetchRequest<TOriginating, TRelated>(methodInfo, query, relatedObjectSelector);
+ }
+
+ public static FluentFetchRequest<TOriginating, TRelated> FetchMany<TOriginating, TRelated>(
+ this IQueryable<TOriginating> query, Expression<Func<TOriginating, IEnumerable<TRelated>>> relatedObjectSelector)
+ {
+ ArgumentUtility.CheckNotNull("query", query);
+ ArgumentUtility.CheckNotNull("relatedObjectSelector", relatedObjectSelector);
+
+ var methodInfo = ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TOriginating), typeof(TRelated));
+ return CreateFluentFetchRequest<TOriginating, TRelated>(methodInfo, query, relatedObjectSelector);
+ }
+
+ public static FluentFetchRequest<TQueried, TRelated> ThenFetch<TQueried, TFetch, TRelated>(
+ this FluentFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, TRelated>> relatedObjectSelector)
+ {
+ ArgumentUtility.CheckNotNull("query", query);
+ ArgumentUtility.CheckNotNull("relatedObjectSelector", relatedObjectSelector);
+
+ var methodInfo = ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TQueried), typeof(TFetch), typeof(TRelated));
+ return CreateFluentFetchRequest<TQueried, TRelated>(methodInfo, query, relatedObjectSelector);
+ }
+
+ public static FluentFetchRequest<TQueried, TRelated> ThenFetchMany<TQueried, TFetch, TRelated>(
+ this FluentFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, IEnumerable<TRelated>>> relatedObjectSelector)
+ {
+ ArgumentUtility.CheckNotNull("query", query);
+ ArgumentUtility.CheckNotNull("relatedObjectSelector", relatedObjectSelector);
+
+ var methodInfo = ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TQueried), typeof(TFetch), typeof(TRelated));
+ return CreateFluentFetchRequest<TQueried, TRelated>(methodInfo, query, relatedObjectSelector);
+ }
+
+ private static FluentFetchRequest<TOriginating, TRelated> CreateFluentFetchRequest<TOriginating, TRelated>(
+ MethodInfo currentFetchMethod,
+ IQueryable<TOriginating> query,
+ LambdaExpression relatedObjectSelector)
+ {
+ var queryProvider = query.Provider; // ArgumentUtility.CheckNotNullAndType<QueryProviderBase>("query.Provider", query.Provider);
+ var callExpression = Expression.Call(currentFetchMethod, query.Expression, relatedObjectSelector);
+ return new FluentFetchRequest<TOriginating, TRelated>(queryProvider, callExpression);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Expressions/AggregateExpressionNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Expressions/AggregateExpressionNode.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Expressions/AggregateExpressionNode.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -0,0 +1,43 @@
+using System;
+using System.Linq.Expressions;
+using NHibernate.Linq.ResultOperators;
+using Remotion.Data.Linq.Clauses;
+using Remotion.Data.Linq.Parsing.Structure.IntermediateModel;
+
+namespace NHibernate.Linq.Expressions
+{
+ public class AggregateExpressionNode : ResultOperatorExpressionNodeBase
+ {
+ public MethodCallExpressionParseInfo ParseInfo { get; set; }
+ public Expression OptionalSeed { get; set; }
+ public LambdaExpression Accumulator { get; set; }
+ public LambdaExpression OptionalSelector { get; set; }
+
+ public AggregateExpressionNode(MethodCallExpressionParseInfo parseInfo, Expression arg1, Expression arg2, LambdaExpression optionalSelector) : base(parseInfo, null, optionalSelector)
+ {
+ ParseInfo = parseInfo;
+
+ if (arg2 != null)
+ {
+ OptionalSeed = arg1;
+ Accumulator = (LambdaExpression) arg2;
+ }
+ else
+ {
+ Accumulator = (LambdaExpression) arg1;
+ }
+
+ OptionalSelector = optionalSelector;
+ }
+
+ public override Expression Resolve(ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
+ {
+ throw new NotImplementedException();
+ }
+
+ protected override ResultOperatorBase CreateResultOperator(ClauseGenerationContext clauseGenerationContext)
+ {
+ return new AggregateResultOperator(ParseInfo, OptionalSeed, Accumulator, OptionalSelector);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/IntermediateHqlTree.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/IntermediateHqlTree.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/IntermediateHqlTree.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -0,0 +1,145 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using NHibernate.Hql.Ast;
+using NHibernate.Transform;
+using NHibernate.Type;
+
+namespace NHibernate.Linq
+{
+ public class IntermediateHqlTree
+ {
+ private readonly bool _root;
+ private readonly List<Action<IQuery, IDictionary<string, Tuple<object, IType>>>> _additionalCriteria = new List<Action<IQuery, IDictionary<string, Tuple<object, IType>>>>();
+ private readonly List<LambdaExpression> _listTransformers = new List<LambdaExpression>();
+ private readonly List<LambdaExpression> _itemTransformers = new List<LambdaExpression>();
+ private readonly List<LambdaExpression> _postExecuteTransformers = new List<LambdaExpression>();
+ private bool _hasDistinctRootOperator;
+
+ public HqlTreeNode Root { get; private set; }
+ public HqlTreeBuilder TreeBuilder { get; private set; }
+
+ public IntermediateHqlTree(bool root)
+ {
+ _root = root;
+ TreeBuilder = new HqlTreeBuilder();
+ Root = TreeBuilder.Query(TreeBuilder.SelectFrom(TreeBuilder.From()));
+ }
+
+ public ExpressionToHqlTranslationResults GetTranslation()
+ {
+ if (_root)
+ {
+ DetectOuterExists();
+ }
+
+ return new ExpressionToHqlTranslationResults(Root,
+ _itemTransformers,
+ _listTransformers,
+ _postExecuteTransformers,
+ _additionalCriteria);
+ }
+
+ public void AddDistinctRootOperator()
+ {
+ if (!_hasDistinctRootOperator)
+ {
+ Expression<Func<IEnumerable<object>, IList>> x =
+ l => new DistinctRootEntityResultTransformer().TransformList(l.ToList());
+
+ _listTransformers.Add(x);
+ _hasDistinctRootOperator = true;
+ }
+ }
+
+
+ public void AddItemTransformer(LambdaExpression transformer)
+ {
+ _itemTransformers.Add(transformer);
+ }
+
+ public void AddFromClause(HqlTreeNode from)
+ {
+ Root.NodesPreOrder.Where(n => n is HqlFrom).First().AddChild(from);
+ }
+
+ public void AddSelectClause(HqlTreeNode select)
+ {
+ Root.NodesPreOrder.Where(n => n is HqlSelectFrom).First().AddChild(select);
+ }
+
+ public void AddGroupByClause(HqlGroupBy groupBy)
+ {
+ Root.As<HqlQuery>().AddChild(groupBy);
+ }
+
+ public void AddOrderByClause(HqlExpression orderBy, HqlDirectionStatement direction)
+ {
+ var orderByRoot = Root.NodesPreOrder.Where(n => n is HqlOrderBy).FirstOrDefault();
+
+ if (orderByRoot == null)
+ {
+ orderByRoot = TreeBuilder.OrderBy();
+ Root.As<HqlQuery>().AddChild(orderByRoot);
+ }
+
+ orderByRoot.AddChild(orderBy);
+ orderByRoot.AddChild(direction);
+ }
+
+ public void AddWhereClause(HqlBooleanExpression where)
+ {
+ var currentWhere = Root.NodesPreOrder.Where(n => n is HqlWhere).FirstOrDefault();
+
+ if (currentWhere == null)
+ {
+ currentWhere = TreeBuilder.Where(where);
+ Root.As<HqlQuery>().AddChild(currentWhere);
+ }
+ else
+ {
+ var currentClause = (HqlBooleanExpression)currentWhere.Children.Single();
+
+ currentWhere.ClearChildren();
+ currentWhere.AddChild(TreeBuilder.BooleanAnd(currentClause, where));
+ }
+ }
+
+ private void DetectOuterExists()
+ {
+ if (Root is HqlExists)
+ {
+ Root = Root.Children.First();
+
+ _additionalCriteria.Add((q, p) => q.SetMaxResults(1));
+
+ Expression<Func<IEnumerable<object>, bool>> x = l => l.Any();
+
+ _listTransformers.Add(x);
+ }
+ }
+
+
+ public void AddAdditionalCriteria(Action<IQuery, IDictionary<string, Tuple<object, IType>>> criteria)
+ {
+ _additionalCriteria.Add(criteria);
+ }
+
+ public void AddPostExecuteTransformer(LambdaExpression lambda)
+ {
+ _postExecuteTransformers.Add(lambda);
+ }
+
+ public void AddListTransformer(LambdaExpression lambda)
+ {
+ _listTransformers.Add(lambda);
+ }
+
+ public void SetRoot(HqlTreeNode newRoot)
+ {
+ Root = newRoot;
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -19,6 +19,11 @@
}
}
+ public static bool IsEnumerableOfT(this System.Type type)
+ {
+ return type.IsGenericType && type.GetGenericTypeDefinition() == typeof (IEnumerable<>);
+ }
+
public static bool IsNullable(this System.Type type)
{
return (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>));
Modified: trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -1,17 +1,11 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using NHibernate.Engine.Query;
using NHibernate.Hql.Ast.ANTLR.Tree;
-using NHibernate.Linq.ResultOperators;
using NHibernate.Linq.Visitors;
using NHibernate.Type;
-using Remotion.Data.Linq;
-using Remotion.Data.Linq.Clauses;
using Remotion.Data.Linq.Parsing.ExpressionTreeVisitors;
-using Remotion.Data.Linq.Parsing.Structure;
-using Remotion.Data.Linq.Parsing.Structure.IntermediateModel;
namespace NHibernate.Linq
{
@@ -83,118 +77,4 @@
return _astNode;
}
}
-
- public static class NhRelinqQueryParser
- {
- public static readonly MethodCallExpressionNodeTypeRegistry MethodCallRegistry =
- MethodCallExpressionNodeTypeRegistry.CreateDefault();
-
- static NhRelinqQueryParser()
- {
- MethodCallRegistry.Register(
- new[]
- {
- MethodCallExpressionNodeTypeRegistry.GetRegisterableMethodDefinition(ReflectionHelper.GetMethod(() => Queryable.Aggregate<object>(null, null))),
- MethodCallExpressionNodeTypeRegistry.GetRegisterableMethodDefinition(ReflectionHelper.GetMethod(() => Queryable.Aggregate<object, object>(null, null, null)))
- },
- typeof (AggregateExpressionNode));
-
- MethodCallRegistry.Register(
- new []
- {
- MethodCallExpressionNodeTypeRegistry.GetRegisterableMethodDefinition(ReflectionHelper.GetMethod((List<object> l) => l.Contains(null))),
-
- },
- typeof(ContainsExpressionNode));
- }
-
- public static QueryModel Parse(Expression expression)
- {
- return new QueryParser(new ExpressionTreeParser(MethodCallRegistry)).GetParsedQuery(expression);
- }
- }
-
- public class NameUnNamedParameters : NhExpressionTreeVisitor
- {
- public static Expression Visit(Expression expression)
- {
- var visitor = new NameUnNamedParameters();
-
- return visitor.VisitExpression(expression);
- }
-
- private readonly Dictionary<ParameterExpression, ParameterExpression> _renamedParameters = new Dictionary<ParameterExpression, ParameterExpression>();
-
- protected override Expression VisitParameterExpression(ParameterExpression expression)
- {
- if (string.IsNullOrEmpty(expression.Name))
- {
- ParameterExpression renamed;
-
- if (_renamedParameters.TryGetValue(expression, out renamed))
- {
- return renamed;
- }
-
- renamed = Expression.Parameter(expression.Type, Guid.NewGuid().ToString());
-
- _renamedParameters.Add(expression, renamed);
-
- return renamed;
- }
-
- return base.VisitParameterExpression(expression);
- }
- }
-
- public class AggregateExpressionNode : ResultOperatorExpressionNodeBase
- {
- public MethodCallExpressionParseInfo ParseInfo { get; set; }
- public Expression OptionalSeed { get; set; }
- public LambdaExpression Accumulator { get; set; }
- public LambdaExpression OptionalSelector { get; set; }
-
- public AggregateExpressionNode(MethodCallExpressionParseInfo parseInfo, Expression arg1, Expression arg2, LambdaExpression optionalSelector) : base(parseInfo, null, optionalSelector)
- {
- ParseInfo = parseInfo;
-
- if (arg2 != null)
- {
- OptionalSeed = arg1;
- Accumulator = (LambdaExpression) arg2;
- }
- else
- {
- Accumulator = (LambdaExpression) arg1;
- }
-
- OptionalSelector = optionalSelector;
- }
-
- public override Expression Resolve(ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
- {
- throw new NotImplementedException();
- }
-
- protected override ResultOperatorBase CreateResultOperator(ClauseGenerationContext clauseGenerationContext)
- {
- return new AggregateResultOperator(ParseInfo, OptionalSeed, Accumulator, OptionalSelector);
- }
- }
-
- public class AggregateResultOperator : ClientSideTransformOperator
- {
- public MethodCallExpressionParseInfo ParseInfo { get; set; }
- public Expression OptionalSeed { get; set; }
- public LambdaExpression Accumulator { get; set; }
- public LambdaExpression OptionalSelector { get; set; }
-
- public AggregateResultOperator(MethodCallExpressionParseInfo parseInfo, Expression optionalSeed, LambdaExpression accumulator, LambdaExpression optionalSelector)
- {
- ParseInfo = parseInfo;
- OptionalSeed = optionalSeed;
- Accumulator = accumulator;
- OptionalSelector = optionalSelector;
- }
- }
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -1,5 +1,4 @@
-using System;
-using System.Collections;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
Added: trunk/nhibernate/src/NHibernate/Linq/NhRelinqQueryParser.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/NhRelinqQueryParser.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/NhRelinqQueryParser.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -0,0 +1,50 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using Remotion.Data.Linq;
+using Remotion.Data.Linq.EagerFetching.Parsing;
+using Remotion.Data.Linq.Parsing.Structure;
+using Remotion.Data.Linq.Parsing.Structure.IntermediateModel;
+using AggregateExpressionNode = NHibernate.Linq.Expressions.AggregateExpressionNode;
+
+namespace NHibernate.Linq
+{
+ public static class NhRelinqQueryParser
+ {
+ public static readonly MethodCallExpressionNodeTypeRegistry MethodCallRegistry =
+ MethodCallExpressionNodeTypeRegistry.CreateDefault();
+
+ static NhRelinqQueryParser()
+ {
+ MethodCallRegistry.Register(
+ new[]
+ {
+ MethodCallExpressionNodeTypeRegistry.GetRegisterableMethodDefinition(
+ ReflectionHelper.GetMethod(() => Queryable.Aggregate<object>(null, null))),
+ MethodCallExpressionNodeTypeRegistry.GetRegisterableMethodDefinition(
+ ReflectionHelper.GetMethod(() => Queryable.Aggregate<object, object>(null, null, null)))
+ },
+ typeof (AggregateExpressionNode));
+
+ MethodCallRegistry.Register(
+ new[]
+ {
+ MethodCallExpressionNodeTypeRegistry.GetRegisterableMethodDefinition(
+ ReflectionHelper.GetMethod((List<object> l) => l.Contains(null))),
+
+ },
+ typeof (ContainsExpressionNode));
+
+ MethodCallRegistry.Register(new[] { typeof(EagerFetchingExtensionMethods).GetMethod("Fetch") }, typeof(FetchOneExpressionNode));
+ MethodCallRegistry.Register(new[] { typeof(EagerFetchingExtensionMethods).GetMethod("FetchMany") }, typeof(FetchManyExpressionNode));
+ MethodCallRegistry.Register(new[] { typeof(EagerFetchingExtensionMethods).GetMethod("ThenFetch") }, typeof(ThenFetchOneExpressionNode));
+ MethodCallRegistry.Register(new[] { typeof(EagerFetchingExtensionMethods).GetMethod("ThenFetchMany") }, typeof(ThenFetchManyExpressionNode));
+
+ }
+
+ public static QueryModel Parse(Expression expression)
+ {
+ return new QueryParser(new ExpressionTreeParser(MethodCallRegistry)).GetParsedQuery(expression);
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -56,7 +56,7 @@
return swapper.VisitExpression(expression);
}
- protected override Expression VisitExpression(Expression expression)
+ public override Expression VisitExpression(Expression expression)
{
if (expression == null)
{
Added: trunk/nhibernate/src/NHibernate/Linq/ResultOperators/AggregateResultOperator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/ResultOperators/AggregateResultOperator.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/ResultOperators/AggregateResultOperator.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -0,0 +1,21 @@
+using System.Linq.Expressions;
+using Remotion.Data.Linq.Parsing.Structure.IntermediateModel;
+
+namespace NHibernate.Linq.ResultOperators
+{
+ public class AggregateResultOperator : ClientSideTransformOperator
+ {
+ public MethodCallExpressionParseInfo ParseInfo { get; set; }
+ public Expression OptionalSeed { get; set; }
+ public LambdaExpression Accumulator { get; set; }
+ public LambdaExpression OptionalSelector { get; set; }
+
+ public AggregateResultOperator(MethodCallExpressionParseInfo parseInfo, Expression optionalSeed, LambdaExpression accumulator, LambdaExpression optionalSelector)
+ {
+ ParseInfo = parseInfo;
+ OptionalSeed = optionalSeed;
+ Accumulator = accumulator;
+ OptionalSelector = optionalSelector;
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -2,7 +2,6 @@
using System.Collections.ObjectModel;
using System.Linq.Expressions;
using System.Text;
-using Remotion.Data.Linq.Parsing;
namespace NHibernate.Linq.Visitors
{
@@ -13,7 +12,7 @@
/// generate the same key as
/// from c in Customers where c.City = "Madrid"
/// </summary>
- public class ExpressionKeyVisitor : ExpressionTreeVisitor
+ public class ExpressionKeyVisitor : NhExpressionTreeVisitor
{
private readonly IDictionary<ConstantExpression, NamedParameter> _constantToParameterMap;
readonly StringBuilder _string = new StringBuilder();
@@ -93,22 +92,14 @@
return base.VisitElementInit(elementInit);
}
- protected override ReadOnlyCollection<T> VisitExpressionList<T>(ReadOnlyCollection<T> expressions)
- {
- if (expressions.Count > 0)
- {
- VisitExpression(expressions[0]);
+ private T AppendCommas<T>(T expression) where T : Expression
+ {
+ VisitExpression(expression);
+ _string.Append(", ");
- for (var i = 1; i < expressions.Count; i++)
- {
- _string.Append(", ");
- VisitExpression(expressions[i]);
- }
- }
+ return expression;
+ }
- return expressions;
- }
-
protected override Expression VisitInvocationExpression(InvocationExpression expression)
{
return base.VisitInvocationExpression(expression);
@@ -117,7 +108,8 @@
protected override Expression VisitLambdaExpression(LambdaExpression expression)
{
_string.Append('(');
- VisitExpressionList(expression.Parameters);
+
+ VisitList(expression.Parameters, AppendCommas);
_string.Append(") => (");
VisitExpression(expression.Body);
_string.Append(')');
@@ -171,7 +163,7 @@
_string.Append('.');
_string.Append(expression.Method.Name);
_string.Append('(');
- VisitExpressionList(expression.Arguments);
+ VisitList(expression.Arguments, AppendCommas);
_string.Append(')');
return expression;
@@ -187,7 +179,7 @@
_string.Append("new ");
_string.Append(expression.Constructor.DeclaringType.Name);
_string.Append('(');
- VisitExpressionList(expression.Arguments);
+ VisitList(expression.Arguments, AppendCommas);
_string.Append(')');
return expression;
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -2,14 +2,13 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
-using Remotion.Data.Linq.Parsing;
namespace NHibernate.Linq.Visitors
{
/// <summary>
/// Locates constants in the expression tree and generates parameters for each one
/// </summary>
- public class ExpressionParameterVisitor : ExpressionTreeVisitor
+ public class ExpressionParameterVisitor : NhExpressionTreeVisitor
{
private readonly Dictionary<ConstantExpression, NamedParameter> _parameters = new Dictionary<ConstantExpression, NamedParameter>();
Added: trunk/nhibernate/src/NHibernate/Linq/Visitors/NameUnNamedParameters.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/NameUnNamedParameters.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/NameUnNamedParameters.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+namespace NHibernate.Linq.Visitors
+{
+ public class NameUnNamedParameters : NhExpressionTreeVisitor
+ {
+ public static Expression Visit(Expression expression)
+ {
+ var visitor = new NameUnNamedParameters();
+
+ return visitor.VisitExpression(expression);
+ }
+
+ private readonly Dictionary<ParameterExpression, ParameterExpression> _renamedParameters = new Dictionary<ParameterExpression, ParameterExpression>();
+
+ protected override Expression VisitParameterExpression(ParameterExpression expression)
+ {
+ if (string.IsNullOrEmpty(expression.Name))
+ {
+ ParameterExpression renamed;
+
+ if (_renamedParameters.TryGetValue(expression, out renamed))
+ {
+ return renamed;
+ }
+
+ renamed = Expression.Parameter(expression.Type, Guid.NewGuid().ToString());
+
+ _renamedParameters.Add(expression, renamed);
+
+ return renamed;
+ }
+
+ return base.VisitParameterExpression(expression);
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -7,7 +7,7 @@
{
public class NhExpressionTreeVisitor : ExpressionTreeVisitor
{
- protected override Expression VisitExpression(Expression expression)
+ public override Expression VisitExpression(Expression expression)
{
if (expression == null)
{
@@ -27,7 +27,6 @@
return VisitNhNew((NhNewExpression) expression);
case NhExpressionType.Star:
return VisitNhStar((NhStarExpression) expression);
-
}
return base.VisitExpression(expression);
@@ -42,7 +41,7 @@
protected virtual Expression VisitNhNew(NhNewExpression expression)
{
- var arguments = VisitExpressionList(expression.Arguments);
+ var arguments = VisitAndConvert(expression.Arguments, "VisitNhNew");
return arguments != expression.Arguments ? new NhNewExpression(expression.Members, arguments) : expression;
}
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -7,7 +7,7 @@
{
public abstract class NhThrowingExpressionTreeVisitor : ThrowingExpressionTreeVisitor
{
- protected override Expression VisitExpression(Expression expression)
+ public override Expression VisitExpression(Expression expression)
{
switch ((NhExpressionType)expression.NodeType)
{
@@ -125,7 +125,7 @@
protected Expression BaseVisitNhNew(NhNewExpression expression)
{
- var arguments = base.VisitExpressionList(expression.Arguments);
+ var arguments = base.VisitAndConvert(expression.Arguments, "BaseVisitNhNew");
return arguments != expression.Arguments ? new NhNewExpression(expression.Members, arguments) : expression;
}
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/Nominator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/Nominator.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/Nominator.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -28,7 +28,7 @@
return _candidates;
}
- protected override Expression VisitExpression(Expression expression)
+ public override Expression VisitExpression(Expression expression)
{
if (expression != null)
{
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using NHibernate.Hql.Ast;
@@ -8,12 +7,13 @@
using NHibernate.Linq.ResultOperators;
using NHibernate.Linq.ReWriters;
using NHibernate.Linq.Visitors.ResultOperatorProcessors;
-using NHibernate.Type;
using Remotion.Data.Linq;
using Remotion.Data.Linq.Clauses;
using Remotion.Data.Linq.Clauses.Expressions;
using Remotion.Data.Linq.Clauses.ResultOperators;
using Remotion.Data.Linq.Clauses.StreamedData;
+using Remotion.Data.Linq.EagerFetching;
+using AggregateResultOperator = NHibernate.Linq.ResultOperators.AggregateResultOperator;
namespace NHibernate.Linq.Visitors
{
@@ -48,23 +48,16 @@
var visitor = new QueryModelVisitor(parameters, root, queryModel);
visitor.Visit();
- return visitor.GetTranslation();
+ return visitor._hqlTree.GetTranslation();
}
+ private readonly IntermediateHqlTree _hqlTree;
private static readonly ResultOperatorMap ResultOperatorMap;
-
- private readonly List<Action<IQuery, IDictionary<string, Tuple<object, IType>>>> _additionalCriteria = new List<Action<IQuery, IDictionary<string, Tuple<object, IType>>>>();
- private readonly List<LambdaExpression> _listTransformers = new List<LambdaExpression>();
- private readonly List<LambdaExpression> _itemTransformers = new List<LambdaExpression>();
- private readonly List<LambdaExpression> _postExecuteTransformers = new List<LambdaExpression>();
- private readonly bool _root;
private bool _serverSide = true;
- public HqlTreeNode Root { get; private set; }
public VisitorParameters VisitorParameters { get; private set; }
public IStreamedDataInfo CurrentEvaluationType { get; private set; }
public IStreamedDataInfo PreviousEvaluationType { get; private set; }
- public HqlTreeBuilder TreeBuilder { get; private set; }
public QueryModel Model { get; private set; }
static QueryModelVisitor()
@@ -82,15 +75,16 @@
ResultOperatorMap.Add<ClientSideSelect, ProcessClientSideSelect>();
ResultOperatorMap.Add<AnyResultOperator, ProcessAny>();
ResultOperatorMap.Add<AllResultOperator, ProcessAll>();
+ ResultOperatorMap.Add<FetchOneRequest, ProcessFetchOne>();
+ ResultOperatorMap.Add<FetchManyRequest, ProcessFetchMany>();
}
private QueryModelVisitor(VisitorParameters visitorParameters, bool root, QueryModel queryModel)
{
VisitorParameters = visitorParameters;
Model = queryModel;
- _root = root;
- TreeBuilder = new HqlTreeBuilder();
- Root = TreeBuilder.Query(TreeBuilder.SelectFrom(TreeBuilder.From()));
+
+ _hqlTree = new IntermediateHqlTree(root);
}
private void Visit()
@@ -98,92 +92,15 @@
VisitQueryModel(Model);
}
-
- private ExpressionToHqlTranslationResults GetTranslation()
- {
- if (_root)
- {
- DetectOuterExists();
- }
-
- return new ExpressionToHqlTranslationResults(Root,
- _itemTransformers,
- _listTransformers,
- _postExecuteTransformers,
- _additionalCriteria);
- }
-
- private void DetectOuterExists()
- {
- if (Root is HqlExists)
- {
- Root = Root.Children.First();
-
- _additionalCriteria.Add((q, p) => q.SetMaxResults(1));
-
- Expression<Func<IEnumerable<object>, bool>> x = l => l.Any();
-
- _listTransformers.Add(x);
- }
- }
-
public override void VisitMainFromClause(MainFromClause fromClause, QueryModel queryModel)
{
- AddFromClause(TreeBuilder.Range(
- HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters),
- TreeBuilder.Alias(fromClause.ItemName)));
+ _hqlTree.AddFromClause(_hqlTree.TreeBuilder.Range(
+ HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters),
+ _hqlTree.TreeBuilder.Alias(fromClause.ItemName)));
base.VisitMainFromClause(fromClause, queryModel);
}
-
- private void AddWhereClause(HqlBooleanExpression where)
- {
- var currentWhere = Root.NodesPreOrder.Where(n => n is HqlWhere).FirstOrDefault();
-
- if (currentWhere == null)
- {
- currentWhere = TreeBuilder.Where(where);
- Root.As<HqlQuery>().AddChild(currentWhere);
- }
- else
- {
- var currentClause = (HqlBooleanExpression)currentWhere.Children.Single();
-
- currentWhere.ClearChildren();
- currentWhere.AddChild(TreeBuilder.BooleanAnd(currentClause, where));
- }
- }
-
- private void AddFromClause(HqlTreeNode from)
- {
- Root.NodesPreOrder.Where(n => n is HqlFrom).First().AddChild(from);
- }
-
- private void AddSelectClause(HqlTreeNode select)
- {
- Root.NodesPreOrder.Where(n => n is HqlSelectFrom).First().AddChild(select);
- }
-
- private void AddGroupByClause(HqlGroupBy groupBy)
- {
- Root.As<HqlQuery>().AddChild(groupBy);
- }
-
- private void AddOrderByClause(HqlExpression orderBy, HqlDirectionStatement direction)
- {
- var orderByRoot = Root.NodesPreOrder.Where(n => n is HqlOrderBy).FirstOrDefault();
-
- if (orderByRoot == null)
- {
- orderByRoot = TreeBuilder.OrderBy();
- Root.As<HqlQuery>().AddChild(orderByRoot);
- }
-
- orderByRoot.AddChild(orderBy);
- orderByRoot.AddChild(direction);
- }
-
public override void VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, int index)
{
PreviousEvaluationType = CurrentEvaluationType;
@@ -201,32 +118,7 @@
}
}
- var results = ResultOperatorMap.Process(resultOperator, this);
-
- if (results.AdditionalCriteria != null)
- {
- _additionalCriteria.Add(results.AdditionalCriteria);
- }
- if (results.GroupBy != null)
- {
- AddGroupByClause(results.GroupBy);
- }
- if (results.ListTransformer != null)
- {
- _listTransformers.Add(results.ListTransformer);
- }
- if (results.PostExecuteTransformer != null)
- {
- _postExecuteTransformers.Add(results.PostExecuteTransformer);
- }
- if (results.WhereClause != null)
- {
- AddWhereClause(results.WhereClause);
- }
- if (results.TreeNode != null)
- {
- Root = results.TreeNode;
- }
+ ResultOperatorMap.Process(resultOperator, this, _hqlTree);
}
private void GroupBy<TSource, TKey, TResult>(Expression<Func<TSource, TKey>> keySelector, Expression<Func<TSource, TResult>> elementSelector)
@@ -246,10 +138,10 @@
if (visitor.ProjectionExpression != null)
{
- _itemTransformers.Add(visitor.ProjectionExpression);
+ _hqlTree.AddItemTransformer(visitor.ProjectionExpression);
}
- AddSelectClause(TreeBuilder.Select(visitor.GetHqlNodes()));
+ _hqlTree.AddSelectClause(_hqlTree.TreeBuilder.Select(visitor.GetHqlNodes()));
base.VisitSelectClause(selectClause, queryModel);
}
@@ -257,17 +149,17 @@
public override void VisitWhereClause(WhereClause whereClause, QueryModel queryModel, int index)
{
// Visit the predicate to build the query
- AddWhereClause(HqlGeneratorExpressionTreeVisitor.Visit(whereClause.Predicate, VisitorParameters).AsBooleanExpression());
+ _hqlTree.AddWhereClause(HqlGeneratorExpressionTreeVisitor.Visit(whereClause.Predicate, VisitorParameters).AsBooleanExpression());
}
public override void VisitOrderByClause(OrderByClause orderByClause, QueryModel queryModel, int index)
{
foreach (Ordering clause in orderByClause.Orderings)
{
- AddOrderByClause(HqlGeneratorExpressionTreeVisitor.Visit(clause.Expression, VisitorParameters).AsExpression(),
+ _hqlTree.AddOrderByClause(HqlGeneratorExpressionTreeVisitor.Visit(clause.Expression, VisitorParameters).AsExpression(),
clause.OrderingDirection == OrderingDirection.Asc
- ? TreeBuilder.Ascending()
- : (HqlDirectionStatement) TreeBuilder.Descending());
+ ? _hqlTree.TreeBuilder.Ascending()
+ : (HqlDirectionStatement) _hqlTree.TreeBuilder.Descending());
}
}
@@ -276,10 +168,10 @@
var equalityVisitor = new EqualityHqlGenerator(VisitorParameters);
var whereClause = equalityVisitor.Visit(joinClause.InnerKeySelector, joinClause.OuterKeySelector);
- AddWhereClause(whereClause);
+ _hqlTree.AddWhereClause(whereClause);
- AddFromClause(TreeBuilder.Range(HqlGeneratorExpressionTreeVisitor.Visit(joinClause.InnerSequence, VisitorParameters),
- TreeBuilder.Alias(joinClause.ItemName)));
+ _hqlTree.AddFromClause(_hqlTree.TreeBuilder.Range(HqlGeneratorExpressionTreeVisitor.Visit(joinClause.InnerSequence, VisitorParameters),
+ _hqlTree.TreeBuilder.Alias(joinClause.ItemName)));
}
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index)
@@ -287,9 +179,9 @@
if (fromClause is LeftJoinClause)
{
// It's a left join
- AddFromClause(TreeBuilder.LeftJoin(
+ _hqlTree.AddFromClause(_hqlTree.TreeBuilder.LeftJoin(
HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters).AsExpression(),
- TreeBuilder.Alias(fromClause.ItemName)));
+ _hqlTree.TreeBuilder.Alias(fromClause.ItemName)));
}
else if (fromClause.FromExpression is MemberExpression)
{
@@ -298,9 +190,9 @@
if (member.Expression is QuerySourceReferenceExpression)
{
// It's a join
- AddFromClause(TreeBuilder.Join(
+ _hqlTree.AddFromClause(_hqlTree.TreeBuilder.Join(
HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters).AsExpression(),
- TreeBuilder.Alias(fromClause.ItemName)));
+ _hqlTree.TreeBuilder.Alias(fromClause.ItemName)));
}
else
{
@@ -311,9 +203,9 @@
else
{
// TODO - exact same code as in MainFromClause; refactor this out
- AddFromClause(TreeBuilder.Range(
+ _hqlTree.AddFromClause(_hqlTree.TreeBuilder.Range(
HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters),
- TreeBuilder.Alias(fromClause.ItemName)));
+ _hqlTree.TreeBuilder.Alias(fromClause.ItemName)));
}
Added: trunk/nhibernate/src/NHibernate/Linq/Visitors/QuerySourceLocator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/QuerySourceLocator.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/QuerySourceLocator.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -0,0 +1,37 @@
+using Remotion.Data.Linq;
+using Remotion.Data.Linq.Clauses;
+
+namespace NHibernate.Linq.Visitors
+{
+ public class QuerySourceLocator : QueryModelVisitorBase
+ {
+ private readonly System.Type _type;
+ private IQuerySource _querySource;
+
+ private QuerySourceLocator(System.Type type)
+ {
+ _type = type;
+ }
+
+ public static IQuerySource FindQuerySource(QueryModel queryModel, System.Type type)
+ {
+ var finder = new QuerySourceLocator(type);
+
+ finder.VisitQueryModel(queryModel);
+
+ return finder._querySource;
+ }
+
+ public override void VisitMainFromClause(MainFromClause fromClause, QueryModel queryModel)
+ {
+ if (_type == fromClause.ItemType)
+ {
+ _querySource = fromClause;
+ }
+ else
+ {
+ base.VisitMainFromClause(fromClause, queryModel);
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/IResultOperatorProcessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/IResultOperatorProcessor.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/IResultOperatorProcessor.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -2,6 +2,6 @@
{
public interface IResultOperatorProcessor<T>
{
- ProcessResultOperatorReturn Process(T resultOperator, QueryModelVisitor queryModelVisitor);
+ void Process(T resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree);
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAggregate.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAggregate.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAggregate.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -2,12 +2,13 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
+using NHibernate.Linq.ResultOperators;
namespace NHibernate.Linq.Visitors.ResultOperatorProcessors
{
public class ProcessAggregate : IResultOperatorProcessor<AggregateResultOperator>
{
- public ProcessResultOperatorReturn Process(AggregateResultOperator resultOperator, QueryModelVisitor queryModelVisitor)
+ public void Process(AggregateResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
{
var inputType = resultOperator.Accumulator.Parameters[1].Type;
var accumulatorType = resultOperator.Accumulator.Parameters[0].Type;
@@ -57,7 +58,7 @@
);
}
- return new ProcessResultOperatorReturn { ListTransformer = Expression.Lambda(call, inputList) };
+ tree.AddListTransformer(Expression.Lambda(call, inputList));
}
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAll.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAll.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAll.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -5,15 +5,13 @@
{
public class ProcessAll : IResultOperatorProcessor<AllResultOperator>
{
- public ProcessResultOperatorReturn Process(AllResultOperator resultOperator, QueryModelVisitor queryModelVisitor)
+ public void Process(AllResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
{
- return new ProcessResultOperatorReturn
- {
- WhereClause = queryModelVisitor.TreeBuilder.BooleanNot(
+ tree.AddWhereClause(tree.TreeBuilder.BooleanNot(
HqlGeneratorExpressionTreeVisitor.Visit(resultOperator.Predicate, queryModelVisitor.VisitorParameters).
- AsBooleanExpression()),
- TreeNode = queryModelVisitor.TreeBuilder.BooleanNot(queryModelVisitor.TreeBuilder.Exists((HqlQuery)queryModelVisitor.Root))
- };
+ AsBooleanExpression()));
+
+ tree.SetRoot(tree.TreeBuilder.BooleanNot(tree.TreeBuilder.Exists((HqlQuery) tree.Root)));
}
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAny.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAny.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAny.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -5,12 +5,9 @@
{
public class ProcessAny : IResultOperatorProcessor<AnyResultOperator>
{
- public ProcessResultOperatorReturn Process(AnyResultOperator anyOperator, QueryModelVisitor queryModelVisitor)
+ public void Process(AnyResultOperator anyOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
{
- return new ProcessResultOperatorReturn
- {
- TreeNode = queryModelVisitor.TreeBuilder.Exists((HqlQuery) queryModelVisitor.Root)
- };
+ tree.SetRoot(tree.TreeBuilder.Exists((HqlQuery) tree.Root));
}
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessClientSideSelect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessClientSideSelect.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessClientSideSelect.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -7,7 +7,7 @@
{
public class ProcessClientSideSelect : IResultOperatorProcessor<ClientSideSelect>
{
- public ProcessResultOperatorReturn Process(ClientSideSelect resultOperator, QueryModelVisitor queryModelVisitor)
+ public void Process(ClientSideSelect resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
{
var inputType = resultOperator.SelectClause.Parameters[0].Type;
var outputType = resultOperator.SelectClause.Type.GetGenericArguments()[1];
@@ -22,7 +22,7 @@
Expression.Call(selectMethod, inputList, resultOperator.SelectClause)),
inputList);
- return new ProcessResultOperatorReturn {ListTransformer = lambda};
+ tree.AddListTransformer(lambda);
}
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs 2010-02-24 21:23:13 UTC (rev 4947)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs 2010-02-26 20:47:09 UTC (rev 4948)
@@ -6,30 +6,27 @@
{
public class ProcessContains : IResultOperatorProcessor<ContainsResultOperator>
{
- public ProcessResultOperatorReturn Process(ContainsResultOperator resultOperator, QueryModelVisitor queryModelVisitor)
+ public void Process(ContainsResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
{
var itemExpression =
HqlGeneratorExpressionTreeVisitor.Visit(resultOperator.Item, queryModelVisitor.VisitorParameters)
.AsExpression();
- var from = GetFromRangeClause(queryModelVisitor.Root);
+ var from = GetFromRangeClause(tree.Root);
var source = from.Children.First();
if (source is HqlParameter)
{
// This is an "in" style statement
- return new ProcessResultOperatorReturn {TreeNode = queryModelVisitor.TreeBuilder.In(itemExpression, source)};
+ tree.SetRoot(tree.TreeBuilder.In(itemExpression, source));
}
else
{
// This is an "exists" style statement
- return new ProcessResultOperatorReturn
- {
- ...
[truncated message content] |