Mercurial > pub > bltoolkit
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(); + } + } +}