From: <te...@us...> - 2008-08-28 20:57:11
|
Revision: 3735 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3735&view=rev Author: tehlike Date: 2008-08-28 20:57:17 +0000 (Thu, 28 Aug 2008) Log Message: ----------- Initial NHExpression -> SQL translator. No entity initialization is implemented. Modified tree structure. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Linq/Expressions/ProjectionExpression.cs trunk/nhibernate/src/NHibernate.Linq/Expressions/SelectExpression.cs trunk/nhibernate/src/NHibernate.Linq/NHibernate.Linq.csproj trunk/nhibernate/src/NHibernate.Linq/NHibernateQueryProvider.cs trunk/nhibernate/src/NHibernate.Linq/Util/LinqUtil.cs trunk/nhibernate/src/NHibernate.Linq/Visitors/LogicalExpressionReducer.cs trunk/nhibernate/src/NHibernate.Linq/Visitors/NHibernateExpressionVisitor.cs trunk/nhibernate/src/NHibernate.Linq.Test/GlobalSetup.cs trunk/nhibernate/src/NHibernate.Linq.Test/Model/Animal.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate.Linq/Expressions/NHExpression.cs trunk/nhibernate/src/NHibernate.Linq/Expressions/NHExpressionType.cs trunk/nhibernate/src/NHibernate.Linq/Expressions/PropertyExpression.cs trunk/nhibernate/src/NHibernate.Linq/Expressions/QuerySourceExpression.cs trunk/nhibernate/src/NHibernate.Linq/Loaders/ trunk/nhibernate/src/NHibernate.Linq/Visitors/AssociationRewriteVisitor.cs trunk/nhibernate/src/NHibernate.Linq/Visitors/NHExpressionToSqlExpressionTransformer.cs trunk/nhibernate/src/NHibernate.Linq/Visitors/NHExpressionToSqlQueryTranslator.cs trunk/nhibernate/src/NHibernate.Linq/Visitors/SqlExpressionToSqlStringVisitor.cs Removed Paths: ------------- trunk/nhibernate/src/NHibernate.Linq/Expressions/EntityExpression.cs trunk/nhibernate/src/NHibernate.Linq/Expressions/SelectFragment.cs trunk/nhibernate/src/NHibernate.Linq/Expressions/SqlExpression.cs trunk/nhibernate/src/NHibernate.Linq/Expressions/SqlExpressionType.cs trunk/nhibernate/src/NHibernate.Linq/Visitors/NhibernateExpressionTransformer.cs trunk/nhibernate/src/NHibernate.Linq/Visitors/QueryTransformer.cs Deleted: trunk/nhibernate/src/NHibernate.Linq/Expressions/EntityExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Expressions/EntityExpression.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/Expressions/EntityExpression.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using NHibernate.Metadata; - -namespace NHibernate.Linq.Expressions -{ - /// <summary> - /// An entity is where we want to execute our query on, in RDBMS case it is a Table. - /// May also be used in from clause of a select expression - /// </summary> - public class EntityExpression:SqlExpression - { - public EntityExpression(System.Type type, string alias) - : base(SqlExpressionType.Entity, type) - { - this.Alias = alias; - } - - public string Alias { get; protected set; } - - public override string ToString() - { - return string.Format("(({0}) as {1}", Type.ToString(), this.Alias); - } - } -} Copied: trunk/nhibernate/src/NHibernate.Linq/Expressions/NHExpression.cs (from rev 3726, trunk/nhibernate/src/NHibernate.Linq/Expressions/SqlExpression.cs) =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Expressions/NHExpression.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Linq/Expressions/NHExpression.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace NHibernate.Linq.Expressions +{ + /// <summary> + /// Base expression for transformed nodes. + /// </summary> + public abstract class NHExpression:Expression + { + /// <summary> + /// Base class for the modified nodes. + /// </summary> + /// <param name="nodeType"></param> + /// <param name="type"></param> + protected NHExpression(NHExpressionType nodeType, System.Type type) + : base((ExpressionType)nodeType, type) + { + + } + } +} Property changes on: trunk/nhibernate/src/NHibernate.Linq/Expressions/NHExpression.cs ___________________________________________________________________ Added: svn:mergeinfo + Copied: trunk/nhibernate/src/NHibernate.Linq/Expressions/NHExpressionType.cs (from rev 3726, trunk/nhibernate/src/NHibernate.Linq/Expressions/SqlExpressionType.cs) =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Expressions/NHExpressionType.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Linq/Expressions/NHExpressionType.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NHibernate.Linq.Expressions +{ + public enum NHExpressionType + { + QuerySource=100, + Select, + Projection, + Property, + } +} Property changes on: trunk/nhibernate/src/NHibernate.Linq/Expressions/NHExpressionType.cs ___________________________________________________________________ Added: svn:mergeinfo + Modified: trunk/nhibernate/src/NHibernate.Linq/Expressions/ProjectionExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Expressions/ProjectionExpression.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/Expressions/ProjectionExpression.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -6,22 +6,20 @@ namespace NHibernate.Linq.Expressions { - /// <summary> - /// Projection expression - /// </summary> - public class ProjectionExpression:SqlExpression + public class ProjectionExpression:NHExpression { - public ProjectionExpression(SelectExpression source, Expression lambda) - : base(SqlExpressionType.Projection, lambda.Type) + public ProjectionExpression(SelectExpression source, Expression projector) + : base(NHExpressionType.Projection, projector.Type) { - this.Projector = lambda; + this.Projector = projector; + this.Source = source; } public Expression Projector { get; protected set; } - public SelectExpression Source { get; set; } + public SelectExpression Source { get; protected set; } public override string ToString() { - return string.Format("({0})", this.Projector.ToString()); + return string.Format("({0})", this.Projector); } } } Added: trunk/nhibernate/src/NHibernate.Linq/Expressions/PropertyExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Expressions/PropertyExpression.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Linq/Expressions/PropertyExpression.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Net; +using System.Text; +using NHibernate.Metadata; +using NHibernate.Type; + +namespace NHibernate.Linq.Expressions +{ + public class PropertyExpression:NHExpression + { + public PropertyExpression(string name, + System.Type type, Expression expression, IType nhibernateType) + : this(name, type, expression,nhibernateType, NHExpressionType.Property) + { + + } + + + + protected PropertyExpression(string name, System.Type type,Expression expression, IType nhibernateType, NHExpressionType nodeType) + : base(nodeType, type) + { + this.NHibernateType = nhibernateType; + this.Expression = expression; + this.Name = name; + } + + public Expression Expression { get; protected set; } + public IType NHibernateType { get; protected set; } + public string Name { get; protected set; } + + public override string ToString() + { + return this.Expression.ToString() + "." + Name; + } + } +} Copied: trunk/nhibernate/src/NHibernate.Linq/Expressions/QuerySourceExpression.cs (from rev 3726, trunk/nhibernate/src/NHibernate.Linq/Expressions/EntityExpression.cs) =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Expressions/QuerySourceExpression.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Linq/Expressions/QuerySourceExpression.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using NHibernate.Metadata; + +namespace NHibernate.Linq.Expressions +{ + /// <summary> + /// A QuerySource expression is where we want to execute our query on, in RDBMS case it is a physical Table in general. + /// May also be used in from clause of a select expression + /// </summary> + public class QuerySourceExpression:NHExpression + { + public QuerySourceExpression(IQueryable query) + : base(NHExpressionType.QuerySource, query.GetType()) + { + + this.Query = query; + } + + public IQueryable Query { get; protected set; } + + public override string ToString() + { + return string.Format("(({0})", Type.ToString()); + } + } +} Modified: trunk/nhibernate/src/NHibernate.Linq/Expressions/SelectExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Expressions/SelectExpression.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/Expressions/SelectExpression.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -9,17 +9,19 @@ /// <summary> /// A select expression is executed against the database to retrieve data. /// </summary> - public class SelectExpression : SqlExpression + public class SelectExpression : NHExpression { - public SelectExpression(System.Type type, string alias, Expression from, Expression where) - : base(SqlExpressionType.Select, type) + public SelectExpression(System.Type type, string alias, Expression projection, Expression from, Expression where) + : base(NHExpressionType.Select, type) { this.Where = where; this.From = from; - this.Alias = alias; + this.FromAlias = alias; + this.Projection = projection; } - public string Alias { get; set; } + public Expression Projection { get; protected set; } + public string FromAlias { get; protected set; } public Expression Where { get; protected set; } public Expression From { get; protected set; } } Deleted: trunk/nhibernate/src/NHibernate.Linq/Expressions/SelectFragment.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Expressions/SelectFragment.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/Expressions/SelectFragment.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace NHibernate.Linq.Expressions -{ - public class SelectFragment - { - public SelectFragment(string alias,SqlExpression expression) - { - this.Alias = alias; - this.Expression = expression; - } - - public string Alias { get; protected set; } - public SqlExpression Expression { get; protected set; } - public override string ToString() - { - return string.Format("({0} as {1})", Expression.ToString(),Alias); - } - } -} Deleted: trunk/nhibernate/src/NHibernate.Linq/Expressions/SqlExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Expressions/SqlExpression.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/Expressions/SqlExpression.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; - -namespace NHibernate.Linq.Expressions -{ - /// <summary> - /// Base expression for transformed nodes. - /// </summary> - public abstract class SqlExpression:Expression - { - /// <summary> - /// Base class for the modified nodes. - /// </summary> - /// <param name="nodeType"></param> - /// <param name="type"></param> - protected SqlExpression(SqlExpressionType nodeType, System.Type type) - : base((ExpressionType)nodeType, type) - { - - } - } -} Deleted: trunk/nhibernate/src/NHibernate.Linq/Expressions/SqlExpressionType.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Expressions/SqlExpressionType.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/Expressions/SqlExpressionType.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace NHibernate.Linq.Expressions -{ - public enum SqlExpressionType - { - Entity=100, - Select, - Projection, - } -} Modified: trunk/nhibernate/src/NHibernate.Linq/NHibernate.Linq.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/NHibernate.Linq.csproj 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/NHibernate.Linq.csproj 2008-08-28 20:57:17 UTC (rev 3735) @@ -47,13 +47,14 @@ </ItemGroup> <ItemGroup> <Compile Include="Expressions\ProjectionExpression.cs" /> + <Compile Include="Expressions\PropertyExpression.cs" /> <Compile Include="Expressions\SelectExpression.cs" /> - <Compile Include="Expressions\SelectFragment.cs" /> - <Compile Include="Expressions\SqlExpression.cs" /> - <Compile Include="Expressions\SqlExpressionType.cs" /> - <Compile Include="Expressions\EntityExpression.cs" /> + <Compile Include="Expressions\NHExpression.cs" /> + <Compile Include="Expressions\NHExpressionType.cs" /> + <Compile Include="Expressions\QuerySourceExpression.cs" /> <Compile Include="Util\Guard.cs" /> <Compile Include="Util\LinqUtil.cs" /> + <Compile Include="Visitors\AssociationRewriteVisitor.cs" /> <Compile Include="Visitors\LogicalExpressionReducer.cs" /> <Compile Include="ExpressionVisitor.cs" /> <Compile Include="NHibernateExtensions.cs" /> @@ -62,10 +63,14 @@ <Compile Include="QueryProvider.cs" /> <Compile Include="Util\TypeSystem.cs" /> <Compile Include="Visitors\LocalVariableExpressionReducer.cs" /> - <Compile Include="Visitors\NhibernateExpressionTransformer.cs" /> <Compile Include="Visitors\NHibernateExpressionVisitor.cs" /> - <Compile Include="Visitors\QueryTransformer.cs" /> + <Compile Include="Visitors\NHExpressionToSqlQueryTranslator.cs" /> + <Compile Include="Visitors\SqlExpressionToSqlStringVisitor.cs" /> + <Compile Include="Visitors\NHExpressionToSqlExpressionTransformer.cs" /> </ItemGroup> + <ItemGroup> + <Folder Include="Loaders\" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. Modified: trunk/nhibernate/src/NHibernate.Linq/NHibernateQueryProvider.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/NHibernateQueryProvider.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/NHibernateQueryProvider.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -1,8 +1,11 @@ using System; using NHibernate.Criterion; using NHibernate.Linq.Util; +using NHibernate.SqlCommand; using Expression=System.Linq.Expressions.Expression; using NHibernate.Linq.Visitors; +using NHibernate.Engine; +using System.Collections.Generic; namespace NHibernate.Linq { @@ -18,12 +21,14 @@ public override object Execute(Expression expression) { + IList<object> parameterList = new List<object>(); + ISessionFactoryImplementor sessionFactory = this.session.SessionFactory as ISessionFactoryImplementor; + expression = LocalVariableExpressionReducer.Reduce(expression); + expression = LogicalExpressionReducer.Reduce(expression); + expression = AssociationRewriteVisitor.Rewrite(expression, sessionFactory); + expression = NHExpressionToSqlExpressionTransformer.Transform(sessionFactory, expression); + SqlString sql=SqlExpressionToSqlStringVisitor.Translate(expression, sessionFactory,parameterList); throw new NotImplementedException(); - - /* iteratively process expression tree here converting to NH tree */ - - //expression = LocalVariableExpressionReducer.Reduce(expression); - //expression = LogicalExpressionReducer.Reduce(expression); //expression = AssociationVisitor.RewriteWithAssociations(session.SessionFactory, expression); //expression = CollectionAliasVisitor.AssignCollectionAccessAliases(expression); //expression = new PropertyToMethodVisitor().Visit(expression); @@ -32,8 +37,8 @@ //once tree is converted to NH tree, pass it to NHibernateQueryTranslator //which will convert the tree to an NHibernate.SqlCommand.SqlString - //NHibernateQueryTranslator translator = new NHibernateQueryTranslator(session); - //return translator.Translate(expression,this.queryOptions); + + //return translator.Transform(expression,this.queryOptions); } } } Modified: trunk/nhibernate/src/NHibernate.Linq/Util/LinqUtil.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Util/LinqUtil.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/Util/LinqUtil.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -16,5 +16,10 @@ } return expression; } + public static bool IsAnonymousType(System.Type type) + { + return type != null && type.Name.StartsWith("<"); + } + } } Added: trunk/nhibernate/src/NHibernate.Linq/Visitors/AssociationRewriteVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Visitors/AssociationRewriteVisitor.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Linq/Visitors/AssociationRewriteVisitor.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -0,0 +1,72 @@ +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using NHibernate.Linq.Expressions; +using NHibernate.Linq.Util; +using NHibernate.Metadata; +using NHibernate.Type; + +namespace NHibernate.Linq.Visitors +{ + public class AssociationRewriteVisitor:NHibernateExpressionVisitor + { + public static Expression Rewrite(Expression expr,ISessionFactory factory) + { + var visitor=new AssociationRewriteVisitor(factory); + expr=visitor.Visit(expr); + return expr; + } + + public AssociationRewriteVisitor(ISessionFactory factory) + { + this.sessionFactory = factory; + this.aliasOrder = 0; + + } + private readonly ISessionFactory sessionFactory; + + private IClassMetadata GetMetaData(System.Type type) + { + if (!LinqUtil.IsAnonymousType(type)) + { + try + { + return sessionFactory.GetClassMetadata(type); + } + catch (MappingException) + { + + } + } + return null; + } + + private string GetNextAlias() + { + return "source" + (aliasOrder++).ToString(); + } + + private int aliasOrder; + + protected override Expression VisitMemberAccess(MemberExpression expr) + { + expr = (MemberExpression)base.VisitMemberAccess(expr); + IClassMetadata clazz = GetMetaData(expr.Member.DeclaringType); + IType propertyType = clazz.GetPropertyType(expr.Member.Name); + if(propertyType.IsAssociationType||propertyType.IsComponentType) + { + return new PropertyExpression(expr.Member.Name, ((PropertyInfo)expr.Member).PropertyType, base.Visit(expr.Expression), propertyType); + } + else + { + return new PropertyExpression(expr.Member.Name, ((PropertyInfo)expr.Member).PropertyType, base.Visit(expr.Expression), propertyType); + } + } + protected override Expression VisitConstant(ConstantExpression c) + { + if (c.Value is IQueryable) + return new QuerySourceExpression((IQueryable) c.Value); + return c; + } + } +} Property changes on: trunk/nhibernate/src/NHibernate.Linq/Visitors/AssociationRewriteVisitor.cs ___________________________________________________________________ Added: svn:mergeinfo + Modified: trunk/nhibernate/src/NHibernate.Linq/Visitors/LogicalExpressionReducer.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Visitors/LogicalExpressionReducer.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/Visitors/LogicalExpressionReducer.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -12,7 +12,7 @@ /// </summary> //May be used for animal.Offspring.Any() == true - //Eventhough it is almost unnecessary to reduce not(not(true)) kind of expression(sql servers can easily optimize them, + //Eventhough it is almost unnecessary to reduce not(not(true)) kind of expression(sql servers can easily optimize them, but //simplified expressions is gold for debugging. public class LogicalExpressionReducer:ExpressionVisitor { Added: trunk/nhibernate/src/NHibernate.Linq/Visitors/NHExpressionToSqlExpressionTransformer.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Visitors/NHExpressionToSqlExpressionTransformer.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Linq/Visitors/NHExpressionToSqlExpressionTransformer.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using NHibernate.Impl; +using NHibernate.Linq.Expressions; +using NHibernate.Linq.Util; +using NHibernate.Metadata; +using NHibernate.SqlCommand; +using NHibernate.Type; +using NHibernate.Mapping; +using NHibernate.Engine; +using NHibernate.Persister.Entity; +using IQueryable=System.Linq.IQueryable; + +namespace NHibernate.Linq.Visitors +{ + public class NHExpressionToSqlExpressionTransformer : NHibernateExpressionVisitor + { + public static Expression Transform(ISessionFactory factory,Expression expr) + { + return new NHExpressionToSqlExpressionTransformer(factory as ISessionFactoryImplementor).Visit(expr); + } + + public NHExpressionToSqlExpressionTransformer(ISessionFactoryImplementor sessionFactory) + { + this.sessionFactory = sessionFactory; + } + + private readonly ISessionFactoryImplementor sessionFactory; + + protected override Expression VisitMethodCall(MethodCallExpression m) + { + if(m.Method.DeclaringType==typeof(Enumerable)||m.Method.DeclaringType==typeof(Queryable)) + { + if(m.Method.Name=="Where") + { + return TransformWhereCall(m); + } + else if(m.Method.Name=="Select") + { + return TransformSelectCall(m); + } + } + return base.VisitMethodCall(m); + } + protected Expression TransformSelectCall(MethodCallExpression expr) + { + Expression source = this.Visit(expr.Arguments[0]); + LambdaExpression lambda = LinqUtil.StripQuotes(expr.Arguments[1]) as LambdaExpression; + Expression body = lambda.Body; + ParameterExpression parameter = lambda.Parameters[0]; + string alias = parameter.Name; + System.Type type = lambda.Body.Type; + System.Type resultType = typeof(IQueryable<>).MakeGenericType(type); + return new SelectExpression(resultType, alias, body, source, null); + } + + protected Expression TransformWhereCall(MethodCallExpression expr) + { + Expression source = this.Visit(expr.Arguments[0]); + Expression expression = expr.Arguments[1]; + LambdaExpression lambda = LinqUtil.StripQuotes(expr.Arguments[1]) as LambdaExpression; + Expression body = lambda.Body; + body=this.Visit(lambda.Body); + ParameterExpression parameter = lambda.Parameters[0]; + string alias = parameter.Name; + System.Type type = body.Type; + System.Type resultType = typeof(IQueryable<>).MakeGenericType(type); + return new SelectExpression(resultType, alias, null, source, body); + } + + protected override Expression VisitQuerySource(QuerySourceExpression expr) + { + return expr; + } + + + protected override Expression VisitBinary(BinaryExpression b) + { + switch(b.NodeType) + { + case ExpressionType.NotEqual://NOT EQUAL requires special handling since sql servers need expressions like NOT(x=y) + { + Expression eq = Expression.Equal(b.Left, b.Right); + return Expression.Not(eq); + } + default: + return base.VisitBinary(b); + } + + } + } +} Property changes on: trunk/nhibernate/src/NHibernate.Linq/Visitors/NHExpressionToSqlExpressionTransformer.cs ___________________________________________________________________ Added: svn:mergeinfo + Copied: trunk/nhibernate/src/NHibernate.Linq/Visitors/NHExpressionToSqlQueryTranslator.cs (from rev 3726, trunk/nhibernate/src/NHibernate.Linq/Visitors/QueryTransformer.cs) =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Visitors/NHExpressionToSqlQueryTranslator.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Linq/Visitors/NHExpressionToSqlQueryTranslator.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using NHibernate.SqlCommand; + +namespace NHibernate.Linq.Visitors +{ + public class NHExpressionToSqlQueryTranslator:NHibernateExpressionVisitor + { + protected SqlStringBuilder sqlStringBuilder; + public SqlString Translate(Expression expression) + { + this.sqlStringBuilder = new SqlStringBuilder(); + this.Visit(expression); + return sqlStringBuilder.ToSqlString(); + } + protected override Expression VisitSelect(NHibernate.Linq.Expressions.SelectExpression select) + { + return select; + } + protected override Expression VisitMethodCall(MethodCallExpression m) + { + return base.VisitMethodCall(m); + } + } +} Property changes on: trunk/nhibernate/src/NHibernate.Linq/Visitors/NHExpressionToSqlQueryTranslator.cs ___________________________________________________________________ Added: svn:mergeinfo + Modified: trunk/nhibernate/src/NHibernate.Linq/Visitors/NHibernateExpressionVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Visitors/NHibernateExpressionVisitor.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/Visitors/NHibernateExpressionVisitor.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -16,14 +16,16 @@ { if(exp==null) return null; - switch((SqlExpressionType)exp.NodeType) + switch((NHExpressionType)exp.NodeType) { - case SqlExpressionType.Entity: - return this.VisitEntity((EntityExpression)exp); - case SqlExpressionType.Select: + case NHExpressionType.QuerySource: + return this.VisitQuerySource((QuerySourceExpression)exp); + case NHExpressionType.Select: return this.VisitSelect((SelectExpression)exp); - case SqlExpressionType.Projection: + case NHExpressionType.Projection: return this.VisitProjection((ProjectionExpression)exp); + case NHExpressionType.Property: + return this.VisitProperty((PropertyExpression)exp); default: return base.Visit(exp); } @@ -42,23 +44,28 @@ } protected virtual Expression VisitSource(Expression source) { - return this.Visit(source); + return source; } + protected virtual Expression VisitProperty(PropertyExpression property) + { + return property; + } + //TODO: modify protected virtual Expression VisitSelect(SelectExpression select) { Expression from = this.VisitSource(select.From); Expression where = this.Visit(select.Where); - + Expression projection = this.Visit(select.Projection); if (from != select.From || where != select.Where) { - return new SelectExpression(select.Type, select.Alias, from, where); + return new SelectExpression(select.Type, select.FromAlias, projection, from, where); } else return select; } - protected virtual Expression VisitEntity(EntityExpression expr) + protected virtual Expression VisitQuerySource(QuerySourceExpression expr) { - return this.Visit(expr); + return expr; } } Deleted: trunk/nhibernate/src/NHibernate.Linq/Visitors/NhibernateExpressionTransformer.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Visitors/NhibernateExpressionTransformer.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/Visitors/NhibernateExpressionTransformer.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace NHibernate.Linq.Visitors -{ - public class NhibernateExpressionTransformer:ExpressionVisitor - { - } -} Deleted: trunk/nhibernate/src/NHibernate.Linq/Visitors/QueryTransformer.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Visitors/QueryTransformer.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq/Visitors/QueryTransformer.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace NHibernate.Linq.Visitors -{ - public class QueryTransformer:ExpressionVisitor - { - } -} Added: trunk/nhibernate/src/NHibernate.Linq/Visitors/SqlExpressionToSqlStringVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq/Visitors/SqlExpressionToSqlStringVisitor.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Linq/Visitors/SqlExpressionToSqlStringVisitor.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -0,0 +1,206 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using NHibernate.Engine; +using NHibernate.Linq.Expressions; +using NHibernate.SqlCommand; +using SelectFragment=NHibernate.SqlCommand.SelectFragment; +using NHibernate.Persister.Entity; +using NHibernate.Type; +using NHibernate.Metadata; + +namespace NHibernate.Linq.Visitors +{ + //TODO: Process the query source by converting into select expression + //TODO: Select expression should be changed so that it can handle columns or projections instead of expression. + public class SqlExpressionToSqlStringVisitor:NHibernateExpressionVisitor + { + public static SqlString Translate(Expression expr,ISessionFactoryImplementor sessionFactory,IList<object> parameterList) + { + + var visitor = new SqlExpressionToSqlStringVisitor(sessionFactory,parameterList); + visitor.Visit(expr); + return visitor.selectBuilder.ToSqlString(); + } + + public SqlExpressionToSqlStringVisitor(ISessionFactoryImplementor sessionFactory,IList<object> parameterList) + { + this.selectBuilder = new SqlStringBuilder(); + this.sessionFactory = sessionFactory; + this.parameterList = parameterList; + } + + private readonly IList<object> parameterList; + private ISessionFactoryImplementor sessionFactory; + private SqlStringBuilder selectBuilder; + protected override Expression VisitUnary(UnaryExpression u) + { + switch(u.NodeType) + { + case ExpressionType.Not: + { + selectBuilder.Add(" NOT ("); + Expression ret=base.VisitUnary(u); + selectBuilder.Add(")"); + return ret; + } + case ExpressionType.Negate: + { + selectBuilder.Add("(-1 * ("); + Expression ret = base.VisitUnary(u); + selectBuilder.Add("))"); + return ret; + } + } + return base.VisitUnary(u); + } + protected override Expression VisitBinary(BinaryExpression b) + { + string op = ""; + + #region operators + + switch (b.NodeType) + { + case ExpressionType.Add: + op = "+"; + break; + case ExpressionType.And: + case ExpressionType.AndAlso: + op = "AND"; + break; + case ExpressionType.Divide: + op = "/"; + break; + case ExpressionType.GreaterThan: + op = ">"; + break; + case ExpressionType.GreaterThanOrEqual: + op = ">="; + break; + case ExpressionType.LessThan: + op = "<"; + break; + case ExpressionType.LessThanOrEqual: + op = "<="; + break; + case ExpressionType.Modulo: + op = "MOD"; + break; + case ExpressionType.Multiply: + op = "*"; + break; + case ExpressionType.Or: + case ExpressionType.OrElse: + op = "OR"; + break; + case ExpressionType.Subtract: + op = "-"; + break; + case ExpressionType.Equal: + op = "="; + break; + case ExpressionType.NotEqual: + op = "!="; + break; + case ExpressionType.Power: + default: + throw new NotImplementedException(); + } + + #endregion + + selectBuilder.Add("("); + this.Visit(b.Left); + selectBuilder.Add(" "); + selectBuilder.Add(op); + selectBuilder.Add(" "); + this.Visit(b.Right); + selectBuilder.Add(")"); + return b; + } + protected override Expression VisitConditional(ConditionalExpression c) + { + return base.VisitConditional(c); + } + + protected override Expression VisitConstant(ConstantExpression c) + { + selectBuilder.AddParameter(); + parameterList.Add(c.Value); + return c; + } + + protected override Expression VisitProperty(PropertyExpression property) + { + ParameterExpression expr = property.Expression as ParameterExpression; + + selectBuilder.Add(string.Format("{0}.{1}", expr.Name, property.Name)); + return property; + } + + protected override Expression VisitSelect(SelectExpression select) + { + selectBuilder.Add("(SELECT "); + if(select.Projection!=null) + this.Visit(select.Projection); + else + selectBuilder.Add(select.FromAlias+".* "); + + if (select.From != null) + { + selectBuilder.Add(" FROM ("); + this.Visit(select.From); + selectBuilder.Add(") AS "); + selectBuilder.Add(select.FromAlias); + } + else + throw new NotImplementedException(); + if(select.Where!=null) + { + selectBuilder.Add(" WHERE "); + this.Visit(select.Where); + } + selectBuilder.Add(")"); + return select; + } + + protected override Expression VisitQuerySource(QuerySourceExpression expr) + { + selectBuilder.Add("SELECT "); + IClassMetadata metadata = sessionFactory.GetClassMetadata(expr.Query.ElementType); + IPropertyMapping mapping = (IPropertyMapping)sessionFactory.GetEntityPersister(metadata.EntityName); + string[] names = metadata.PropertyNames; + bool started = false; + for (int i = 0; i < names.Length;i++ ) + { + string name = names[i]; + IType propertyType = metadata.GetPropertyType(name); + if (!(propertyType.IsComponentType | + propertyType.IsCollectionType | + propertyType.IsAssociationType | + propertyType.IsAnyType)) + { + if(started) + selectBuilder.Add(", "); + started = true; + selectBuilder.Add(mapping.ToColumns(name)[0]); + } + + } + selectBuilder.Add(" FROM "); + selectBuilder.Add(expr.Query.ElementType.Name); + return base.VisitQuerySource(expr); + } + protected override Expression VisitParameter(ParameterExpression p) + { + return base.VisitParameter(p); + } + public override string ToString() + { + return selectBuilder.ToString(); + } + } +} Modified: trunk/nhibernate/src/NHibernate.Linq.Test/GlobalSetup.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq.Test/GlobalSetup.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq.Test/GlobalSetup.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -18,11 +18,59 @@ Configuration cfg = new Configuration().Configure(); new SchemaExport(cfg).Execute(false, true, false, true); factory = cfg.BuildSessionFactory(); + GenerateTestData(); } public static void GenerateTestData() { - + ISession session = factory.OpenSession(); + using (ITransaction tx=session.BeginTransaction()) + { + StateProvince province = new StateProvince(); + province.IsoCode = "123456789"; + province.Name = "Sim State"; + + Address zooAddress = new Address(); + zooAddress.City = "Simcity"; + zooAddress.Country = "Sim Country"; + zooAddress.PostalCode = "1234"; + zooAddress.StateProvince = province; + zooAddress.Street = "North Sim street"; + + Zoo zoo1 = new Zoo(); + zoo1.Address = zooAddress; + zoo1.Classification = ClassificationType.Medium; + zoo1.Name = "Jurassic Park"; + + M.Animal animal1 = new Animal(); + animal1.BodyWeight = 10; + animal1.Description = "a persian"; + animal1.SerialNumber = "1000001"; + animal1.Zoo = zoo1; + + M.Animal animal2 = new Animal(); + animal2.BodyWeight = 10; + animal2.Description = "a persian"; + animal2.SerialNumber = "1000002"; + animal2.Zoo = zoo1; + + M.Animal child1 = new Animal(); + child1.BodyWeight = 10; + child1.Description = "a persian, wild"; + child1.SerialNumber = "1000003"; + child1.Mother = animal1; + child1.Father = animal2; + child1.Zoo = zoo1; + + animal1.Offspring.Add(child1); + + session.Save(province); + session.Save(zoo1); + session.Save(animal1); + session.Save(animal2); + session.Save(child1); + tx.Commit(); + } } public static ISession CreateSession() Modified: trunk/nhibernate/src/NHibernate.Linq.Test/Model/Animal.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Linq.Test/Model/Animal.cs 2008-08-24 15:12:16 UTC (rev 3734) +++ trunk/nhibernate/src/NHibernate.Linq.Test/Model/Animal.cs 2008-08-28 20:57:17 UTC (rev 3735) @@ -6,6 +6,10 @@ { public class Animal { + public Animal() + { + this.Offspring = new HashedSet<Animal>(); + } public virtual int Id { get; set; } public virtual string Description { get; set; } public virtual double BodyWeight { get; set; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |