Mercurial > pub > bltoolkit
view UnitTests/Linq/ParserTest.cs @ 9:1e85f66cf767 default tip
update bltoolkit
author | nickolay |
---|---|
date | Thu, 05 Apr 2018 20:53:26 +0300 |
parents | f990fcb411a9 |
children |
line wrap: on
line source
using System; using System.Linq; using System.Linq.Expressions; using System.Reflection; using BLToolkit.Data.Linq; using BLToolkit.Data.Linq.Builder; using BLToolkit.Data.Sql; using Data.Linq.Model; using NUnit.Framework; namespace Data.Linq { [TestFixture] public class ParserTest : TestBase { static ParserTest() { ExpressionBuilder.AddBuilder(new ContextParser()); } #region IsExpressionTable [Test] public void IsExpressionTable1() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => p1.ParentID) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } [Test] public void IsExpressionTable2() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => p1.ParentID + 1) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } [Test] public void IsExpressionTable3() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => p1) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } #endregion #region IsExpressionScalar [Test] public void IsExpressionScalar1() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => p1.ParentID) .Select (p2 => p2) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } [Test] public void IsExpressionScalar2() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => p1.ParentID + 1) .Select (p2 => p2) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } [Test] public void IsExpressionScalar3() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => p1) .Select (p2 => p2) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } [Test] public void IsExpressionScalar4() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => p1.ParentID + 1) .Where (p3 => p3 == 1) .Select (p2 => p2) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Expression). Result); //Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.SubQuery)); } } [Test] public void IsExpressionScalar5() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => p1) .Select (p2 => p2.ParentID) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } [Test] public void IsExpressionScalar6() { using (var db = new TestDbManager()) { var ctx = db.Child .Select (p => p.Parent) .Select (p => p) .GetContext(); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } [Test] public void IsExpressionScalar7() { using (var db = new TestDbManager()) { var ctx = db.Child .Select (p => p) .Select (p => p) .Select (p => p.Parent) .GetContext(); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } [Test] public void IsExpressionScalar8() { using (var db = new TestDbManager()) { var ctx = db.Child .Select (p => p) .Select (p3 => new { p1 = new { p2 = new { p = p3 } } }) .Select (p => p.p1.p2.p.Parent) .GetContext(); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } [Test] public void IsExpressionScalar9() { using (var db = new TestDbManager()) { var ctx = db.Child .Select (p => p) .Select (p3 => new { p1 = new { p2 = new { p = p3.Parent } } }) .Select (p => p.p1.p2.p) .GetContext(); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } [Test] public void IsExpressionScalar10() { using (var db = new TestDbManager()) { var ctx = db.Child .Select (p => p) .Select (p => new { p = new { p } }) .Select (p => p.p) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } [Test] public void IsExpressionScalar11() { using (var db = new TestDbManager()) { var ctx = db.Child .Select (p => p) .Select (p => new { p = new Child { ChildID = p.ChildID } }) .Select (p => p.p) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.SubQuery). Result); } } #endregion #region IsExpressionSelect [Test] public void IsExpressionSelect1() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => new { p1.ParentID }) .Select (p2 => p2.ParentID) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); } } [Test] public void IsExpressionSelect2() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => new { p = p1.ParentID + 1 }) .Select (p2 => p2.p) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Expression). Result); } } [Test] public void IsExpressionSelect3() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => new { p1 }) .Select (p2 => p2.p1) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); } } [Test] public void IsExpressionSelect4() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => new { p = p1.ParentID + 1 }) .Where (p3 => p3.p == 1) .Select (p2 => p2.p) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Expression). Result); } } [Test] public void IsExpressionSelect42() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => new { p = p1.ParentID + 1 }) .Where (p3 => p3.p == 1) .Select (p2 => p2) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Expression). Result); } } [Test] public void IsExpressionSelect5() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => new { p1 }) .Select (p2 => p2.p1.ParentID) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); } } [Test] public void IsExpressionSelect6() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p => new { p }) .Select (p => p) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); } } [Test] public void IsExpressionSelect7() { using (var db = new TestDbManager()) { var ctx = db.Child .Select (p => new { p, p.Parent }) .Select (p => new { p.Parent, p.p.ChildID }) .Select (p => p.Parent) .GetContext(); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); } } [Test] public void IsExpressionSelect8() { using (var db = new TestDbManager()) { var ctx = db.Child .Select (p => new { p, p.Parent }) .Select (p => new { p.Parent.ParentID, p.p.ChildID }) .Select (p => p.ParentID) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); } } [Test] public void IsExpressionSelect9() { using (var db = new TestDbManager()) { var ctx = db.GrandChild .Select (p => new { p, p.Child }) .Select (p => new { p.Child.Parent.ParentID, p.p.ChildID }) .Select (p => p.ParentID) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Expression). Result); } } [Test] public void IsExpressionSelect10() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p => p.Children.Max(c => (int?)c.ChildID) ?? p.Value1) .Select (p => p) .GetContext(); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Association).Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Object). Result); Assert.IsFalse(ctx.IsExpression(null, 0, RequestFor.Field). Result); Assert.IsTrue (ctx.IsExpression(null, 0, RequestFor.Expression). Result); } } #endregion #region ConvertToIndexTable [Test] public void ConvertToIndexTable1() { using (var db = new TestDbManager()) { var ctx = db.Parent1 .Select (t => t) .GetContext(); Assert.AreEqual(new[] { 0, 1 }, ctx.ConvertToIndex(null, 0, ConvertFlags.All).Select(_ => _.Index).ToArray()); Assert.AreEqual(new[] { 0 }, ctx.ConvertToIndex(null, 0, ConvertFlags.Key).Select(_ => _.Index).ToArray()); } } [Test] public void ConvertToIndexTable2() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (t => t) .GetContext(); Assert.AreEqual(new[] { 0, 1 }, ctx.ConvertToIndex(null, 0, ConvertFlags.All).Select(_ => _.Index).ToArray()); Assert.AreEqual(new[] { 0, 1 }, ctx.ConvertToIndex(null, 0, ConvertFlags.Key).Select(_ => _.Index).ToArray()); } } [Test] public void ConvertToIndexTable3() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (t => t.ParentID) .GetContext(); Assert.AreEqual(new[] { 0 }, ctx.ConvertToIndex(null, 0, ConvertFlags.Field).Select(_ => _.Index).ToArray()); } } [Test] public void ConvertToIndexTable4() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (t => t.Value1) .GetContext(); Assert.AreEqual(new[] { 0 }, ctx.ConvertToIndex(null, 0, ConvertFlags.Field).Select(_ => _.Index).ToArray()); } } [Test] public void ConvertToIndexTable5() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (t => new { t = new { t } }) .Select (t => t.t.t.ParentID) .Select (t => t) .GetContext(); Assert.AreEqual(new[] { 0 }, ctx.ConvertToIndex(null, 0, ConvertFlags.Field).Select(_ => _.Index).ToArray()); } } #endregion #region ConvertToIndex [Test] public void ConvertToIndexScalar1() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => p1.ParentID) .Select (p2 => p2) .GetContext(); Assert.AreEqual(new[] { 0 }, ctx.ConvertToIndex(null, 0, ConvertFlags.Field).Select(_ => _.Index).ToArray()); } } [Test] public void ConvertToIndexScalar2() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => p1.ParentID + 1) .Select (p2 => p2) .GetContext(); Assert.AreEqual(new[] { 0 }, ctx.ConvertToIndex(null, 0, ConvertFlags.Field).Select(_ => _.Index).ToArray()); } } [Test] public void ConvertToIndexScalar3() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => p1.ParentID + 1) .Where (p3 => p3 == 1) .Select (p2 => p2) .GetContext(); Assert.AreEqual(new[] { 0 }, ctx.ConvertToIndex(null, 0, ConvertFlags.Field).Select(_ => _.Index).ToArray()); } } [Test] public void ConvertToIndexScalar4() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => new { p = new { p = p1.ParentID } }) .Select (p2 => p2.p.p) .GetContext(); Assert.AreEqual(new[] { 0 }, ctx.ConvertToIndex(null, 0, ConvertFlags.Field).Select(_ => _.Index).ToArray()); } } [Test] public void ConvertToIndexJoin1() { using (var db = new TestDbManager()) { var q2 = from gc1 in db.GrandChild join max in from gch in db.GrandChild group gch by gch.ChildID into g select g.Max(c => c.GrandChildID) on gc1.GrandChildID equals max select gc1; var result = from ch in db.Child join p in db.Parent on ch.ParentID equals p.ParentID join gc2 in q2 on p.ParentID equals gc2.ParentID into g from gc3 in g.DefaultIfEmpty() select gc3; var ctx = result.GetContext(); var idx = ctx.ConvertToIndex(null, 0, ConvertFlags.Key); Assert.AreEqual(new[] { 0, 1, 2 }, idx.Select(_ => _.Index).ToArray()); } } [Test] public void ConvertToIndexJoin2() { using (var db = new TestDbManager()) { var result = from ch in db.Child join gc2 in db.GrandChild on ch.ParentID equals gc2.ParentID into g from gc3 in g.DefaultIfEmpty() select gc3; var ctx = result.GetContext(); var idx = ctx.ConvertToIndex(null, 0, ConvertFlags.Key); Assert.AreEqual(new[] { 0, 1, 2 }, idx.Select(_ => _.Index).ToArray()); idx = ctx.ConvertToIndex(null, 0, ConvertFlags.All); Assert.AreEqual(new[] { 0, 1, 2 }, idx.Select(_ => _.Index).ToArray()); } } #endregion #region ConvertToSql [Test] public void ConvertToSql1() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => new { p1.ParentID }) .Select (p2 => p2.ParentID) .GetContext(); var sql = ctx.ConvertToSql(null, 0, ConvertFlags.Field); Assert.AreEqual (1, sql.Length); Assert.IsAssignableFrom(typeof(SqlField), sql[0].Sql); Assert.AreEqual ("ParentID", ((SqlField)sql[0].Sql).Name); } } [Test] public void ConvertToSql2() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => new { p = p1.ParentID + 1 }) .Select (p2 => p2.p) .GetContext(); var sql = ctx.ConvertToSql(null, 0, ConvertFlags.Field); Assert.AreEqual (1, sql.Length); Assert.IsAssignableFrom(typeof(SqlBinaryExpression), sql[0].Sql); } } [Test] public void ConvertToSql3() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => new { p = p1.ParentID + 1 }) .Where (p3 => p3.p == 1) .Select (p2 => p2.p) .GetContext(); var sql = ctx.ConvertToSql(null, 0, ConvertFlags.Field); Assert.AreEqual (1, sql.Length); Assert.IsAssignableFrom(typeof(SqlQuery.Column), sql[0].Sql); } } [Test] public void ConvertToSql4() { using (var db = new TestDbManager()) { var ctx = db.Parent .Select (p1 => new { p1 }) .Select (p2 => p2.p1.ParentID) .GetContext(); var sql = ctx.ConvertToSql(null, 0, ConvertFlags.Field); Assert.AreEqual (1, sql.Length); Assert.IsAssignableFrom(typeof(SqlField), sql[0].Sql); Assert.AreEqual ("ParentID", ((SqlField)sql[0].Sql).Name); } } [Test] public void ConvertToSql5() { using (var db = new TestDbManager()) { var ctx = db.Child .Select (p => new { p, p.Parent }) .Select (p => new { p.Parent.ParentID, p.p.ChildID }) .Select (p => p.ParentID) .GetContext(); var sql = ctx.ConvertToSql(null, 0, ConvertFlags.Field); Assert.AreEqual (1, sql.Length); Assert.IsAssignableFrom(typeof(SqlField), sql[0].Sql); Assert.AreEqual ("ParentID", ((SqlField)sql[0].Sql).Name); } } #endregion #region SqlTest [Test] public void Join1() { using (var db = new TestDbManager()) { var q = from t in from ch in db.Child join p in db.Parent on ch.ParentID equals p.ParentID select ch.ParentID + p.ParentID where t > 2 select t; var ctx = q.GetContext(); ctx.BuildExpression(null, 0); Assert.AreEqual(1, ctx.SqlQuery.Select.Columns.Count); } } [Test] public void Join2() { using (var db = new TestDbManager()) { var q = from t in from ch in db.Child join p in db.Parent on ch.ParentID equals p.ParentID select new { ID = ch.ParentID + p.ParentID } where t.ID > 2 select t; var ctx = q.GetContext(); ctx.BuildExpression(null, 0); Assert.AreEqual(2, ctx.SqlQuery.Select.Columns.Count); } } public class MyClass { public int ID; } [Test] public void Join3() { using (var db = new TestDbManager()) { var q = from p in db.Parent join j in db.Child on p.ParentID equals j.ParentID select p; var ctx = q.GetContext(); ctx.BuildExpression(null, 0); Assert.AreEqual(2, ctx.SqlQuery.Select.Columns.Count); } } [Test] public void Join4() { using (var db = new TestDbManager()) { var q = from p in db.Parent select new { ID = new MyClass { ID = p.ParentID } } into p join j in from c in db.Child select new { ID = new MyClass { ID = c.ParentID } } on p.ID.ID equals j.ID.ID where p.ID.ID == 1 select p; var ctx = q.GetContext(); ctx.BuildExpression(null, 0); Assert.AreEqual(1, ctx.SqlQuery.Select.Columns.Count); } } [Test] public void Join5() { using (var db = new TestDbManager()) { var q = from p in db.Parent join c in db.Child on p.ParentID equals c.ParentID join g in db.GrandChild on p.ParentID equals g.ParentID select new { p, c, g } into x select x.c.ParentID; var ctx = q.GetContext(); var sql = ctx.ConvertToSql(null, 0, ConvertFlags.All); Assert.AreEqual(1, sql.Length); } } [Test] public void Join6([IncludeDataContexts("Sql2008", "Sql2012")] string context) { using (var db = new TestDbManager(context)) { var q = from g in db.GrandChild join p in db.Parent4 on g.Child.ParentID equals p.ParentID select g; var ctx = q.GetContext(); ctx.BuildExpression(null, 0); var sql = db.GetSqlText(ctx.SqlQuery); CompareSql(sql, @" SELECT [g].[ParentID], [g].[ChildID], [g].[GrandChildID] FROM [GrandChild] [g] LEFT JOIN [Child] [t1] ON [g].[ParentID] = [t1].[ParentID] AND [g].[ChildID] = [t1].[ChildID] INNER JOIN [Parent] [p] ON [t1].[ParentID] = [p].[ParentID]"); } } #endregion } class ContextParser : ISequenceBuilder { public int BuildCounter { get; set; } public bool CanBuild(ExpressionBuilder builder, BuildInfo buildInfo) { var call = buildInfo.Expression as MethodCallExpression; return call != null && call.Method.Name == "GetContext"; } public IBuildContext BuildSequence(ExpressionBuilder builder, BuildInfo buildInfo) { var call = (MethodCallExpression)buildInfo.Expression; return new Context(builder.BuildSequence(new BuildInfo(buildInfo, call.Arguments[0]))); } public SequenceConvertInfo Convert(ExpressionBuilder builder, BuildInfo buildInfo, ParameterExpression param) { return null; } public bool IsSequence(ExpressionBuilder builder, BuildInfo buildInfo) { return builder.IsSequence(new BuildInfo(buildInfo, ((MethodCallExpression)buildInfo.Expression).Arguments[0])); } public class Context : PassThroughContext { public Context(IBuildContext context) : base(context) { } public override void BuildQuery<T>(Query<T> query, ParameterExpression queryParameter) { query.GetElement = (ctx,db,expr,ps) => this; } } } static class Extensions { public static ContextParser.Context GetContext<T>(this IQueryable<T> source) { if (source == null) throw new ArgumentNullException("source"); return source.Provider.Execute<ContextParser.Context>( Expression.Call( null, ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }), new[] { source.Expression })); } static public Expression Unwrap(this Expression ex) { if (ex == null) return null; switch (ex.NodeType) { case ExpressionType.Quote : case ExpressionType.Convert : case ExpressionType.ConvertChecked : return ((UnaryExpression)ex).Operand.Unwrap(); } return ex; } } }