private static IEnumerable <int> CreateObjects <T1, T2, T3, T4, T5, T6, T7>(ISession session, SetterTuple <T1, T2, T3, T4, T5, T6, T7> setters, Func <MyBO, bool> condition)
        {
            var  expectedIds           = new List <int>();
            bool thereAreSomeWithTrue  = false;
            bool thereAreSomeWithFalse = false;
            var  allTestCases          = GetAllTestCases <T1, T2, T3, T4, T5, T6, T7>().ToList();
            var  i = 0;

            foreach (var q in allTestCases)
            {
                MyBO bo = new MyBO();
                setters.Set(bo, session, q.Item1, q.Item2, q.Item3, q.Item4, q.Item5, q.Item6, q.Item7);
                try
                {
                    if (condition(bo))
                    {
                        expectedIds.Add(bo.Id);
                        thereAreSomeWithTrue = true;
                    }
                    else
                    {
                        thereAreSomeWithFalse = true;
                    }
                    if ((i % BatchSize) == 0)
                    {
                        if (session.Transaction.IsActive)
                        {
                            session.Transaction.Commit();
                            session.Clear();
                        }
                        session.BeginTransaction();
                    }
                    session.Save(bo);
                    i++;
                }
                catch (NullReferenceException)
                {
                    // ignore - we only check consistency with Linq2Objects in non-failing cases;
                    // emulating the outer-join logic for exceptional cases in Lin2Objects is IMO very hard.
                }
            }
            if (session.Transaction.IsActive)
            {
                session.Transaction.Commit();
                session.Clear();
            }

            Console.WriteLine("Congratulation!! you have saved " + i + " entities.");
            if (!thereAreSomeWithTrue)
            {
                throw new ArgumentException("Condition is false for all - not a good test", "condition");
            }
            if (!thereAreSomeWithFalse)
            {
                throw new ArgumentException("Condition is true for all - not a good test", "condition");
            }
            return(expectedIds);
        }
        protected void RunTest <T1, T2, T3, T4, T5, T6, T7>(Expression <Func <MyBO, bool> > c1, Expression <Func <MyBO, bool> > c2, SetterTuple <T1, T2, T3, T4, T5, T6, T7> setters)
        {
            int r1 = RunTest(c1, setters);
            int r2 = RunTest(c2, setters);

            Assert.AreEqual(r1, r2);
            Assert.Greater(r1, 0);
        }
        protected int RunTest <T1, T2, T3, T4, T5, T6, T7>(Expression <Func <MyBO, bool> > condition, SetterTuple <T1, T2, T3, T4, T5, T6, T7> setters)
        {
            if (condition == null)
            {
                throw new ArgumentNullException("condition");
            }
            if (setters == null)
            {
                throw new ArgumentNullException("setters");
            }
            IEnumerable <int> expectedIds;

            // Setup
            using (var session = OpenSession())
            {
                expectedIds = CreateObjects(session, setters, condition.Compile());
            }

            try
            {
                // Test
                using (var session = OpenSession())
                {
                    session.CacheMode       = CacheMode.Ignore;
                    session.DefaultReadOnly = true;
                    using (session.BeginTransaction())
                    {
                        return(TestAndAssert(condition, session, expectedIds));
                    }
                }
            }
            finally
            {
                // Teardown
                using (var session = OpenSession())
                {
                    using (var tx = session.BeginTransaction())
                    {
                        DeleteAll <MyBO>(session);
                        DeleteAll <MyRef1>(session);
                        DeleteAll <MyRef2>(session);
                        DeleteAll <MyRef3>(session);
                        tx.Commit();
                    }
                }
            }
        }