diff UnitTests/Linq/SelectManyTest.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UnitTests/Linq/SelectManyTest.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,696 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+
+using BLToolkit.Data.DataProvider;
+
+using NUnit.Framework;
+
+namespace Data.Linq
+{
+	using Model;
+
+	[TestFixture]
+	public class SelectManyTest : TestBase
+	{
+		[Test]
+		public void Basic1()
+		{
+			ForEachProvider(db => AreEqual(
+				   Parent.SelectMany(p =>    Child),
+				db.Parent.SelectMany(p => db.Child)));
+		}
+
+		[Test]
+		public void Basic1_1()
+		{
+			ForEachProvider(db => AreEqual(
+				   Parent.SelectMany(p =>    Child.SelectMany(t =>    GrandChild)),
+				db.Parent.SelectMany(p => db.Child.SelectMany(t => db.GrandChild))));
+		}
+
+		[Test]
+		public void Basic2()
+		{
+			ForEachProvider(db => AreEqual(
+				   Parent.SelectMany(p =>    Child.Select(_ => _.ParentID + 1)),
+				db.Parent.SelectMany(p => db.Child.Select(_ => _.ParentID + 1))));
+		}
+
+		[Test]
+		public void Basic3()
+		{
+			ForEachProvider(db => AreEqual(
+				   Parent.SelectMany(p =>    Child.Select(_ => _.ParentID + 1).Where(_ => _ > 1)),
+				db.Parent.SelectMany(p => db.Child.Select(_ => _.ParentID + 1).Where(_ => _ > 1))));
+		}
+
+		[Test]
+		public void Basic4()
+		{
+			ForEachProvider(db => AreEqual(
+				   Parent.SelectMany(p =>    Child.Select(_ => _.ParentID + 1).Where(_ => p.ParentID == _)),
+				db.Parent.SelectMany(p => db.Child.Select(_ => _.ParentID + 1).Where(_ => p.ParentID == _))));
+		}
+
+        [Test]
+		public void Basic5()
+		{
+			ForEachProvider(new[] { ProviderName.Access }, db => AreEqual(
+				   Child.SelectMany(t => t.Parent.GrandChildren),
+				db.Child.SelectMany(t => t.Parent.GrandChildren)));
+		}
+
+		[Test]
+		public void Basic6()
+		{
+			ForEachProvider(db => AreEqual(
+				   Parent.SelectMany(p => p.Children.Select(_ => _.ParentID + 1).Where(_ => _ > 1)),
+				db.Parent.SelectMany(p => p.Children.Select(_ => _.ParentID + 1).Where(_ => _ > 1))));
+		}
+
+		[Test]
+		public void Basic61()
+		{
+			ForEachProvider(db => AreEqual(
+				   Parent.SelectMany(p => p.Children.Select(_ => _.ParentID + 1).Where(_ => _ > 1 || _ > 2)).Where(_ => _ > 0 || _ > 3),
+				db.Parent.SelectMany(p => p.Children.Select(_ => _.ParentID + 1).Where(_ => _ > 1 || _ > 2)).Where(_ => _ > 0 || _ > 3)));
+		}
+
+        [Test]
+		public void Basic62()
+		{
+			ForEachProvider(new[] { ProviderName.Access },
+				db => AreEqual(
+					   Parent.SelectMany(p => p.Children.Select(_ => _.ParentID + p.ParentID).Where(_ => _ > 1)),
+					db.Parent.SelectMany(p => p.Children.Select(_ => _.ParentID + p.ParentID).Where(_ => _ > 1))));
+		}
+
+		[Test]
+		public void Basic7()
+		{
+			ForEachProvider(db => AreEqual(
+				   Parent.SelectMany(p => p.Children),
+				db.Parent.SelectMany(p => p.Children)));
+		}
+
+		[Test]
+		public void Basic8()
+		{
+			ForEachProvider(db => AreEqual(
+				   Parent.SelectMany(p => p.Children.SelectMany(t => t.GrandChildren)),
+				db.Parent.SelectMany(p => p.Children.SelectMany(t => t.GrandChildren))));
+		}
+
+		[Test]
+		public void Basic9()
+		{
+			ForEachProvider(db => AreEqual(
+				   Parent.SelectMany(p => p.Children.SelectMany(t => p.GrandChildren)),
+				db.Parent.SelectMany(p => p.Children.SelectMany(t => p.GrandChildren))));
+		}
+
+        [Test]
+		public void Basic10()
+		{
+			ForEachProvider(new[] { ProviderName.Access }, db => AreEqual(
+				   Child.GroupBy(o => o.ParentID2).SelectMany(g => g.Select(o => o.Parent)),
+				db.Child.GroupBy(o => o.ParentID2).SelectMany(g => g.Select(o => o.Parent))));
+		}
+
+        [Test]
+		public void Basic11()
+		{
+			ForEachProvider(new[] { ProviderName.Access }, db => AreEqual(
+				   Child
+					.GroupBy(o => o.ParentID2)
+					.SelectMany(g => g.Select(o => o.ParentID)),
+				db.Child
+					.GroupBy(o => o.ParentID2)
+					.SelectMany(g => db.Child.Where(o => o.ParentID2 == g.Key).Select(o => o.ParentID))));
+		}
+
+		[Test]
+		public void Test1()
+		{
+			TestJohn(db =>
+			{
+				var q = db.Person.Select(p => p);
+
+				return db.Person
+					.SelectMany(p1 => q, (p1, p2) => new { p1, p2 })
+					.Where     (t => t.p1.ID == t.p2.ID && t.p1.ID == 1)
+					.Select    (t => new Person { ID = t.p1.ID, FirstName = t.p2.FirstName });
+			});
+		}
+
+		[Test]
+		public void Test11()
+		{
+			TestJohn(db => db.Person
+				.SelectMany(p1 => db.Person.Select(p => p), (p1, p2) => new { p1, p2 })
+				.Where     (t => t.p1.ID == t.p2.ID && t.p1.ID == 1)
+				.Select    (t => new Person { ID = t.p1.ID, FirstName = t.p2.FirstName }));
+		}
+
+		[Test]
+		public void Test21()
+		{
+			TestJohn(db =>
+				from p1 in from p in db.Person select new { ID1 = p.ID, p.LastName  }
+				from p2 in from p in db.Person select new { ID2 = p.ID, p.FirstName }
+				from p3 in from p in db.Person select new { ID3 = p.ID, p.LastName  }
+				where p1.ID1 == p2.ID2 && p1.LastName == p3.LastName && p1.ID1 == 1
+				select new Person { ID = p1.ID1, FirstName = p2.FirstName, LastName = p3.LastName } );
+		}
+
+		[Test]
+		public void Test22()
+		{
+			TestJohn(db =>
+				from p1 in from p in db.Person select p
+				from p2 in from p in db.Person select p
+				from p3 in from p in db.Person select p
+				where p1.ID == p2.ID && p1.LastName == p3.LastName && p1.ID == 1
+				select new Person { ID = p1.ID, FirstName = p2.FirstName, LastName = p3.LastName } );
+		}
+
+		[Test]
+		public void Test31()
+		{
+			TestJohn(db =>
+				from p in
+					from p in
+						from p in db.Person
+						where p.ID == 1
+						select new { p, ID = p.ID + 1 }
+					where p.ID == 2
+					select new { p, ID = p.ID + 1 }
+				where p.ID == 3
+				select p.p.p);
+		}
+
+		[Test]
+		public void Test32()
+		{
+			ForEachProvider(db =>
+			{
+				var q =
+					from p in
+						from p in
+							from p in db.Person
+							where p.ID == 1
+							select new { p, ID = p.ID + 1 }
+						where p.ID == 2
+						select new { p, ID = p.ID + 1 }
+					where p.ID == 3
+					select new { p.p.p };
+
+				var list = q.ToList();
+
+				Assert.AreEqual(1, list.Count);
+
+				var person = list[0].p;
+
+				Assert.AreEqual(1,      person.ID);
+				Assert.AreEqual("John", person.FirstName);
+			});
+		}
+
+		[Test]
+		public void SubQuery1()
+		{
+			TestJohn(db =>
+			{
+				var id = 1;
+				var q  = from p in db.Person where p.ID == id select p;
+
+				return 
+					from p1 in db.Person
+					from p2 in q
+					where p1.ID == p2.ID
+					select new Person { ID = p1.ID, FirstName = p2.FirstName };
+			});
+		}
+
+		public void SubQuery2(ITestDataContext db)
+		{
+			var q1 = from p in db.Person where p.ID == 1 || p.ID == 2 select p;
+			var q2 = from p in db.Person where !(p.ID == 2) select p;
+
+			var q = 
+				from p1 in q1
+				from p2 in q2
+				where p1.ID == p2.ID
+				select new Person { ID = p1.ID, FirstName = p2.FirstName };
+
+			foreach (var person in q)
+			{
+				Assert.AreEqual(1,      person.ID);
+				Assert.AreEqual("John", person.FirstName);
+			}
+		}
+
+		[Test]
+		public void SubQuery2()
+		{
+			ForEachProvider(db =>
+			{
+				SubQuery2(db);
+				SubQuery2(db);
+			});
+		}
+
+		IQueryable<Person> GetPersonQuery(ITestDataContext db, int id)
+		{
+			return from p in db.Person where p.ID == id select new Person { ID = p.ID + 1, FirstName = p.FirstName };
+		}
+
+		[Test]
+		public void SubQuery3()
+		{
+			TestJohn(db =>
+			{
+				var q = GetPersonQuery(db, 1);
+
+				return
+					from p1 in db.Person
+					from p2 in q
+					where p1.ID == p2.ID - 1
+					select new Person { ID = p1.ID, FirstName = p2.FirstName };
+			});
+		}
+
+		[Test]
+		public void OneParam1()
+		{
+			TestJohn(db => db.Person.SelectMany(p => db.Person).Where(t => t.ID == 1).Select(t => t));
+		}
+
+		[Test]
+		public void OneParam2()
+		{
+			ForEachProvider(db => AreEqual(
+				   Parent.SelectMany(p => p.Children).Where(t => t.ParentID == 1).Select(t => t),
+				db.Parent.SelectMany(p => p.Children).Where(t => t.ParentID == 1).Select(t => t)));
+		}
+
+        [Test]
+		public void OneParam3()
+		{
+			ForEachProvider(new[] { ProviderName.Access }, db => AreEqual(
+				   Child.SelectMany(p => p.Parent.GrandChildren).Where(t => t.ParentID == 1).Select(t => t),
+				db.Child.SelectMany(p => p.Parent.GrandChildren).Where(t => t.ParentID == 1).Select(t => t)));
+		}
+
+		[Test]
+		public void ScalarQuery()
+		{
+			TestJohn(db =>
+				from p1 in db.Person
+				from p2 in (from p in db.Person select p.ID)
+				where p1.ID == p2
+				select new Person { ID = p2, FirstName = p1.FirstName }
+			);
+		}
+
+		[Test]
+		public void SelectManyLeftJoin1()
+		{
+			ForEachProvider(db => Assert.AreEqual(
+				(from p in Parent
+				from c in p.Children.Select(o => new { o.ChildID, p.ParentID }).DefaultIfEmpty()
+				select new { p.Value1, o = c }).Count(),
+				(from p in db.Parent
+				from c in p.Children.Select(o => new { o.ChildID, p.ParentID }).DefaultIfEmpty()
+				select new { p.Value1, o = c }).AsEnumerable().Count()));
+		}
+
+		[Test]
+		public void SelectManyLeftJoin2()
+		{
+			ForEachProvider(db => AreEqual(
+				from p in    Parent
+				from ch in (from c in    Child where p.ParentID == c.ParentID select c).DefaultIfEmpty()
+				select ch,
+				from p in db.Parent
+				from ch in (from c in db.Child where p.ParentID == c.ParentID select c).DefaultIfEmpty()
+				select ch));
+		}
+
+        [Test]
+		public void SelectManyLeftJoin3()
+		{
+			ForEachProvider(new[] { ProviderName.Access }, db => AreEqual(
+				from p in Parent
+				from ch in Child.DefaultIfEmpty()
+				where p.ParentID == ch.ParentID
+				select ch,
+				from p in db.Parent
+				from ch in db.Child.DefaultIfEmpty()
+				where p.ParentID == ch.ParentID
+				select ch));
+		}
+
+		[Test]
+		public void SelectManyLeftJoin4()
+		{
+			ForEachProvider(db => AreEqual(
+				from p in Parent
+				from ch in (from c in    Child where p.ParentID == c.ParentID select c).DefaultIfEmpty()
+				select new { p.ParentID, ch },
+				from p in db.Parent
+				from ch in (from c in db.Child where p.ParentID == c.ParentID select c).DefaultIfEmpty()
+				select new { p.ParentID, ch }));
+		}
+
+		[Test]
+		public void SelectManyLeftJoinCount()
+		{
+			var expected =
+				from p in Parent
+				from c in p.Children.Select(o => new { o.ChildID, p.ParentID }).DefaultIfEmpty()
+				select new { p.Value1, o = c };
+
+			ForEachProvider(db => Assert.AreEqual(expected.Count(),
+				(from p in db.Parent
+				from c in p.Children.Select(o => new { o.ChildID, p.ParentID }).DefaultIfEmpty()
+				select new { p.Value1, n = c.ChildID + 1, o = c }).Count()));
+		}
+
+		[Test]
+		public void TestJoin1()
+		{
+			ForEachProvider(db => AreEqual(
+				from p in 
+					from p in Parent
+					from g in p.GrandChildren
+					join c in Child on g.ChildID equals c.ChildID
+					join t in Types on c.ParentID equals t.ID
+					select c
+				join t in Person on p.ParentID equals t.ID
+				select p,
+				from p in 
+					from p in db.Parent
+					from g in p.GrandChildren
+					join c in db.Child on g.ChildID equals c.ChildID
+					join t in db.Types on c.ParentID equals t.ID
+					select c
+				join t in db.Person on p.ParentID equals t.ID
+				select p));
+		}
+
+        [Test]
+		public void Test3()
+		{
+			ForEachProvider(new[] { ProviderName.Access }, db => Assert.AreEqual(
+				(from p in Parent
+				 from g in p.GrandChildren
+				 from t in Person
+				 let c = g.Child
+				 select c).Count(),
+				(from p in db.Parent
+				 from g in p.GrandChildren
+				 from t in db.Person
+				 let c = g.Child
+				 select c).Count()));
+		}
+
+		[Test]
+		public void Test4()
+		{
+			ForEachProvider(db => Assert.AreEqual(
+				(from p in Parent
+				from g in p.GrandChildren
+				join c in db.Child on g.ChildID equals c.ChildID
+				join t in db.Types on c.ParentID equals t.ID
+				select c).Count(),
+				(from p in db.Parent
+				from g in p.GrandChildren
+				join c in db.Child on g.ChildID equals c.ChildID
+				join t in db.Types on c.ParentID equals t.ID
+				select c).Count()));
+		}
+
+        [Test]
+		public void Test5()
+		{
+			ForEachProvider(new[] { ProviderName.Access }, db =>
+			{
+				var q3 =
+					from p in db.Parent
+					from g in db.GrandChild
+					from c in db.Parent2
+					select g.Child;
+
+				q3.ToList();
+			});
+		}
+
+        [Test]
+		public void Test6()
+		{
+			ForEachProvider(new[] { ProviderName.Access }, db =>
+			{
+				var q3 =
+					from p in db.Parent
+					from g in db.GrandChild
+					from c in db.Parent2
+					let r = g.Child
+					select g.Child;
+
+				q3.ToList();
+			});
+		}
+
+        [Test]
+		public void Test7()
+		{
+			ForEachProvider(new[] { ProviderName.Access }, db => AreEqual(
+				from p in db.Parent
+				from g in p.GrandChildren
+				from c in db.Parent2
+				let r = g.Child
+				where p.ParentID == g.ParentID
+				select r,
+				from p in db.Parent
+				from g in p.GrandChildren
+				from c in db.Parent2
+				let r = g.Child
+				where p.ParentID == g.ParentID
+				select r));
+		}
+
+        [Test]
+		public void Test8()
+		{
+			ForEachProvider(new[] { ProviderName.Access }, db =>
+			{
+				var q2 =
+					from p in
+						from p in db.Parent
+						join c in db.GrandChild on p.ParentID equals c.ParentID
+						select p
+					from g in p.GrandChildren
+					from c in db.Parent2
+					let r = g.Child
+					where
+						p.ParentID == g.ParentID
+					select r;
+
+				q2.ToList();
+			});
+		}
+
+		[Test]
+		public void Test81()
+		{
+			ForEachProvider(db =>
+			{
+				var q2 =
+					from p in
+						from p in db.Parent
+						join c in db.GrandChild on p.ParentID equals c.ParentID
+						select p
+					from g in p.GrandChildren
+					//from c in db.Parent2
+					let r = g.Child
+					where
+						p.ParentID == g.ParentID
+					select r;
+
+				q2.ToList();
+			});
+		}
+
+        [Test]
+		public void Test9()
+		{
+			ForEachProvider(new[] { ProviderName.Access }, db =>
+			{
+				var q1 = db.Types.Where(_ => _.ID > 1).Where(_ => _.ID > 2);
+
+				var q2 =
+					from p in db.Parent
+					join c in db.GrandChild on p.ParentID equals c.ParentID
+					join t in q1            on c.ParentID equals t.ID
+					where p.ParentID == 1
+					select p;
+
+				q2 = q2.Distinct().OrderBy(_ => _.ParentID);
+
+				var q3 =
+					from p in q2
+					from g in p.GrandChildren
+					from c in db.Parent2
+					let r = g.Child
+					where
+						p.ParentID == g.ParentID && g.ParentID == c.ParentID
+					select r;
+
+				q3 = q3.Where(_ => _.ChildID == 1);
+
+				q3.ToList();
+			});
+		}
+
+        [Test]
+		public void Test91()
+		{
+			ForEachProvider(new[] { ProviderName.Access }, db =>
+			{
+				var q2 =
+					from p in db.Parent
+					join c in db.GrandChild on p.ParentID equals c.ParentID
+					where p.ParentID == 1
+					select p;
+
+				q2 = q2.Distinct();
+
+				var q3 =
+					from p in q2
+					from g in p.GrandChildren
+					let r = g.Child
+					where
+						p.ParentID == g.ParentID
+					select r;
+
+				q3.ToList();
+			});
+		}
+
+		/////[Test]
+		public void Test92()
+		{
+			ForEachProvider(db => AreEqual(
+				db.Parent
+					.SelectMany(c => c.Children, (c, p) => new { c, p, })
+					.Select(_ => new { _.c, p = new Child { ParentID = _.c.ParentID, ChildID = _.p.ChildID } })
+					.SelectMany(ch => ch.p.GrandChildren, (ch, t) => new { t, ch }),
+				db.Parent
+					.SelectMany(c => c.Children, (c, p) => new { c, p, })
+					.Select(_ => new { _.c, p = new Child { ParentID = _.c.ParentID, ChildID = _.p.ChildID } })
+					.SelectMany(ch => ch.p.GrandChildren, (ch, t) => new { t, ch })));
+		}
+
+		[Test]
+		public void DoubleConntectionTest()
+		{
+			ForEachProvider(db =>
+			{
+				var p1 = 1;
+				var p2 = 1;
+
+				var q1 = db.Parent
+					.GroupJoin(
+						db.Child,
+						x => new { x.ParentID },
+						y => new { y.ParentID },
+						(x,y) => new { Parent = x, Child = y })
+					.SelectMany(
+						y => y.Child.DefaultIfEmpty(),
+						(x,y) => new { x.Parent, Child = x.Child.FirstOrDefault() })
+					.Where(x => x.Parent.Value1 > p1 && x.Parent.ParentID > p2)
+					.OrderBy(x => x.Parent.Value1);
+
+				var q2 =
+					from x in db.Parent
+					join y in db.Child on new { x.ParentID } equals new { y.ParentID } into g
+					from y in g.DefaultIfEmpty()
+					where x.Value1 > p1 && x.ParentID > p2
+					orderby x.Value1
+					select new
+					{
+						x, y
+					};
+
+				var q3 = db.Parent
+					.GroupJoin(
+						db.Child,
+						x => new { x.ParentID },
+						y => new { y.ParentID },
+						(x,y) => new { Parent = x, Child = y })
+					.SelectMany(
+						y => y.Child.DefaultIfEmpty(),
+						(x,y) => new { x.Parent, Child = y })
+					.Where  (x => x.Parent.Value1 > p1 && x.Parent.ParentID > p2)
+					.OrderBy(x => x.Parent.Value1)
+					/*.Select (x => new
+					{
+						x.Parent,
+						x.Child
+					})*/;
+
+				var q4 =
+					from x in db.Parent
+					where x.Value1 > p1 && x.ParentID > p2
+					orderby x.Value1
+					select new
+					{
+						x, y = x.Children.FirstOrDefault()
+					};
+
+				foreach (var item in q1)
+				{
+				}
+			});
+		}
+
+		void Foo(Expression<Func<object[],object>> func)
+		{
+			/*
+				ParameterExpression ps;
+				Expression.Lambda<Func<object[],object>>(
+					Expression.Add(
+						Expression.Convert(
+							Expression.ArrayIndex(
+								ps = Expression.Parameter(typeof(object[]), "p"),
+								Expression.Constant(0, typeof(int))),
+							typeof(string)),
+						Expression.Convert(
+							Expression.Convert(
+								Expression.ArrayIndex(
+									ps,
+									Expression.Constant(1, typeof(int))),
+								typeof(int)),
+							typeof(object)),
+						(MethodInfo)methodof(string.Concat)),
+					new ParameterExpression[] { ps });
+			*/
+		}
+
+		Dictionary<string,string> _dic = new Dictionary<string,string>();
+
+		void Bar()
+		{
+			Foo(p => (string)p[0] + (int)p[1]);
+		}
+
+		//[Test]
+		public void Test___()
+		{
+			Bar();
+		}
+	}
+}