Пример #1
0
        static void Main(string[] args)
        {
            XpoDefault.ConnectionString = MSSqlConnectionProvider.GetConnectionString(".", "sa", "123", "testdb");

            Session
                sessionI = new Session(),
                sessionII;

            UnitOfWork
                unitOfWorkI;

            XPMemberInfo
                memberInfo;

            XPCollection
                xpCollectionI,
                xpCollectionII;

            XPCollection <Staff>
            xpCollectionStaff;

            CriteriaOperator
                criteria;

            TestMaster
                tmpTestMaster,
                tmpTestMasterII;

            TestDetail
                tmpTestDetail,
                tmpTestDetailII;

            TestDE
                tmpTestDE   = null,
                tmpTestDEII = null;

            int
                tmpInt;

            string
                tmpString;

            XPClassInfo
                testMasterClassInfo = sessionI.GetClassInfo <TestMaster>(),
                testDetailClassInfo = sessionI.GetClassInfo <TestDetail>(),
                staffClassInfo      = sessionI.GetClassInfo <Staff>();

            Victim
                tmpVictim;

            #if TEST_PREFETCH_COLLECTION
            if ((tmpTestMaster = sessionI.GetObjectByKey <TestMaster>(2L)) != null)
            {
                foreach (var detail in tmpTestMaster.Details)
                {
                    Debug.WriteLine($"Id: {detail.Id}");
                }
            }

            if ((tmpTestMaster = sessionI.GetObjectByKey <TestMaster>(1L)) != null && (memberInfo = testMasterClassInfo.GetMember(nameof(TestMaster.Details))).MemberType.IsSubclassOf(typeof(XPBaseCollection)))
            {
                if (memberInfo.GetValue(tmpTestMaster) is XPCollection <TestDetail> xpCollectionTestDetails)
                {
                    if (((IXPPrefetchableAssociationList)xpCollectionTestDetails).NeedPrefetch())
                    {
                        criteria = new BinaryOperator(new OperandProperty(nameof(TestDetail.Master)), new OperandValue(tmpTestMaster.Id), BinaryOperatorType.Equal);
                        var details = sessionI.GetObjects(testDetailClassInfo, criteria, null, 0, true, false);
                        ((IXPPrefetchableAssociationList)xpCollectionTestDetails).FinishPrefetch(details);
                        if (!xpCollectionTestDetails.IsLoaded)
                        {
                            xpCollectionTestDetails.Load();
                        }
                    }
                }

                foreach (var detail in tmpTestMaster.Details)
                {
                    Debug.WriteLine($"Id: {detail.Id}");
                }
            }
            #endif

            #if TEST_GENERICS
            xpCollectionI = new XPCollection(sessionI, typeof(Staff));
            //xpCollectionStaff = xpCollectionI as XPCollection<Staff>; // Error CS0039 Cannot convert type 'DevExpress.Xpo.XPCollection' to 'DevExpress.Xpo.XPCollection<TestCollection.Db.Staff>' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion


            Type genericXPCollectionStaff = typeof(XPCollection <>).MakeGenericType(staffClassInfo.ClassType);
            xpCollectionStaff = Activator.CreateInstance(genericXPCollectionStaff, sessionI) as XPCollection <Staff>;
            xpCollectionStaff = new XPCollection <Staff>(sessionI);

            genericXPCollectionStaff = xpCollectionStaff.GetType();
            if (genericXPCollectionStaff.IsGenericType)
            {
                var genericTypeDefinition = genericXPCollectionStaff.GetGenericTypeDefinition();
                if (genericTypeDefinition == typeof(XPCollection <>))
                {
                    Type type = genericXPCollectionStaff.GetGenericArguments()[0];
                    //type = genericXPCollectionStaff.GetProperty("Item").PropertyType;
                    type = genericXPCollectionStaff.GetTypeInfo().GenericTypeArguments[0];
                }

                var xpBaseCollection = (XPBaseCollection)xpCollectionStaff;
            }

            var customCollectionStaff = new CustomCollection <Staff>(sessionI);
            var customCollection      = (XPBaseCollection)customCollectionStaff;

            Type type1       = xpCollectionI.GetType();
            Type elementType = typeof(object);
            Type type2       = typeof(IEnumerable <>).MakeGenericType(elementType);
            Type type3       = typeof(IQueryable <>).MakeGenericType(elementType);
            bool flag        = type2.IsAssignableFrom(type1); // IEnumerable<> false
            flag = type3.IsAssignableFrom(type1);             // IQueryable<> false
            MethodInfo          method1             = (flag ? queryableDistinctInfo : enumerableDistinctInfo).MakeGenericMethod(elementType);
            MethodInfo          method2             = (flag ? queryableOfTypeInfo : enumerableOfTypeInfo).MakeGenericMethod(elementType);
            ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "dataSource");
            UnaryExpression     unaryExpression     = Expression.Convert((Expression)parameterExpression, flag ? type3 : type2);
            var expr = Expression.Lambda <Func <object, object> >((Expression)(true ? Expression.Call(method1, (Expression)unaryExpression) : Expression.Call(method1, (Expression)Expression.Call(method2, (Expression)unaryExpression))), new ParameterExpression[1]
            {
                parameterExpression
            });
            var func = expr.Compile();
            //var result = func(xpCollectionI);

            type1 = xpCollectionStaff.GetType();
            flag  = type2.IsAssignableFrom(type1);    // IEnumerable<> true
            flag  = type3.IsAssignableFrom(type1);    // IQueryable<> false
            var result = func(xpCollectionStaff);
            #endif

            #if TEST_SORTING
            xpCollectionI = new XPCollection(sessionI, typeof(Staff), null, new SortProperty("Dep", SortingDirection.Ascending), new SortProperty("Name", SortingDirection.Ascending));
            foreach (var item in xpCollectionI.OfType <Staff>())
            {
                Debug.WriteLine($"{{Dep:{item.Dep}, Name:\"{item.Name}\"}}");
            }

            xpCollectionII         = new XPCollection(sessionI, typeof(Staff));
            xpCollectionII.Sorting = new SortingCollection {
                new SortProperty("Dep", SortingDirection.Ascending), new SortProperty("Name", SortingDirection.Ascending)
            };
            foreach (var item in xpCollectionII.OfType <Staff>())
            {
                Debug.WriteLine($"{{Dep:{item.Dep}, Name:\"{item.Name}\"}}");
            }
            #endif

            #if TEST_COLLECTION_FROM_COLLECTION
            var baseCollection = new XPCollection <Victim>(sessionI);
            foreach (var item in baseCollection)
            {
                Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
            }

            var falseCollection = new XPCollection(baseCollection, new BinaryOperator(new OperandProperty("FBit"), new OperandValue(false), BinaryOperatorType.Equal));
            foreach (Victim item in falseCollection)
            {
                Debug.WriteLine($"falseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
            }

            var trueCollection = new XPCollection(baseCollection, new BinaryOperator(new OperandProperty("FBit"), new OperandValue(true), BinaryOperatorType.Equal));
            foreach (Victim item in trueCollection)
            {
                Debug.WriteLine($"trueCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
            }

            if ((tmpVictim = ((IBindingList)falseCollection).AddNew() as Victim) != null)
            {
                foreach (var item in baseCollection)
                {
                    Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                foreach (Victim item in falseCollection)
                {
                    Debug.WriteLine($"falseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                tmpVictim.FBit = false;
                foreach (var item in baseCollection)
                {
                    Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                foreach (Victim item in falseCollection)
                {
                    Debug.WriteLine($"falseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                tmpVictim.Save();
                baseCollection.Reload();
                foreach (var item in baseCollection)
                {
                    Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                foreach (Victim item in falseCollection)
                {
                    Debug.WriteLine($"falseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
            }
            if ((tmpVictim = ((IBindingList)falseCollection).AddNew() as Victim) != null)
            {
                foreach (var item in baseCollection)
                {
                    Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                foreach (Victim item in falseCollection)
                {
                    Debug.WriteLine($"falseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                tmpVictim.FBit = true;
                foreach (var item in baseCollection)
                {
                    Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                foreach (Victim item in falseCollection)
                {
                    Debug.WriteLine($"falseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                tmpVictim.Save();
                foreach (var item in baseCollection)
                {
                    Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                foreach (Victim item in falseCollection)
                {
                    Debug.WriteLine($"falseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
            }

            if ((tmpVictim = ((IBindingList)trueCollection).AddNew() as Victim) != null)
            {
                foreach (var item in baseCollection)
                {
                    Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                foreach (Victim item in trueCollection)
                {
                    Debug.WriteLine($"trueCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                tmpVictim.FBit = true;
                foreach (var item in baseCollection)
                {
                    Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                foreach (Victim item in trueCollection)
                {
                    Debug.WriteLine($"trueCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                tmpVictim.Save();
                foreach (var item in baseCollection)
                {
                    Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                foreach (Victim item in trueCollection)
                {
                    Debug.WriteLine($"trueCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
            }
            if ((tmpVictim = ((IBindingList)trueCollection).AddNew() as Victim) != null)
            {
                foreach (var item in baseCollection)
                {
                    Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                foreach (Victim item in trueCollection)
                {
                    Debug.WriteLine($"trueCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                tmpVictim.FBit = false;
                foreach (var item in baseCollection)
                {
                    Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                foreach (Victim item in trueCollection)
                {
                    Debug.WriteLine($"trueCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                tmpVictim.Save();
                foreach (var item in baseCollection)
                {
                    Debug.WriteLine($"baseCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
                foreach (Victim item in trueCollection)
                {
                    Debug.WriteLine($"trueCollection id:{item.Id} f_int:{item.FInt} f_bit:{item.FBit}");
                }
            }
            #endif

            #if TEST_LIFECYCLE
            using (unitOfWorkI = new UnitOfWork())
            {
                xpCollectionI = new XPCollection(typeof(TestMaster));
                AddEventsListeners(xpCollectionI);

                if ((tmpTestMaster = ((IBindingList)xpCollectionI).AddNew() as TestMaster) != null)
                {
                    tmpTestMaster.Name = "Name";
                    tmpTestMaster.Save();
                }

                foreach (TestMaster item in xpCollectionI)
                {
                    System.Diagnostics.Debug.WriteLine(item.Id);
                }
                RemoveEventsListeners(xpCollectionI);
            }
            #endif

            #if TEST_ADD
            using (unitOfWorkI = new UnitOfWork())
            {
                xpCollectionI = new XPCollection(unitOfWorkI, typeof(TestDE));

                    #if TEST_LIFECYCLE
                AddEventsListeners(xpCollectionI);
                    #endif

                if ((tmpTestDE = ((IBindingList)xpCollectionI).AddNew() as TestDE) != null)
                {
                    tmpTestDE.f1 = 1;
                }

                    #if TEST_LIFECYCLE
                RemoveEventsListeners(xpCollectionI);
                    #endif

                tmpTestMaster = new TestMaster(unitOfWorkI);
                    #if TEST_LIFECYCLE
                AddEventsListeners(tmpTestMaster);
                AddEventsListeners(tmpTestMaster.Details);
                    #endif

                if ((tmpTestDetail = ((IBindingList)tmpTestMaster.Details).AddNew() as TestDetail) != null)
                {
                    tmpTestDetail.Name = "blah-blah-blah";
                }

                    #if TEST_LIFECYCLE
                RemoveEventsListeners(tmpTestMaster.Details);
                RemoveEventsListeners(tmpTestMaster);
                    #endif
            }
            #endif

            #if TEST_MODIFY
            using (unitOfWorkI = new UnitOfWork())
            {
                xpCollectionI  = new XPCollection(unitOfWorkI, typeof(TestDE));
                xpCollectionII = new XPCollection(unitOfWorkI, typeof(TestDE));

                criteria = new BinaryOperator(new OperandProperty("id"), new OperandValue(1L), BinaryOperatorType.Equal);

                xpCollectionI.Filter  = criteria;
                xpCollectionII.Filter = criteria;

                if (xpCollectionI.Count != 0)
                {
                    tmpTestDE = xpCollectionI[0] as TestDE;
                }
                if (xpCollectionII.Count != 0)
                {
                    tmpTestDEII = xpCollectionI[0] as TestDE;
                }

                if (tmpTestDE != null)
                {
                    tmpTestDE.f1 = tmpTestDE.f1.HasValue ? tmpTestDE.f1.Value + 1 : 1;
                    tmpTestDE.Save();
                }

                if (tmpTestDEII != null)
                {
                    tmpTestDEII.f1 = tmpTestDEII.f1.HasValue ? tmpTestDEII.f1.Value + 1 : 1;
                    tmpTestDEII.Save();
                }

                unitOfWorkI.CommitChanges();
            }
            #endif

            #if TEST_LOAD
            xpCollectionI = new XPCollection(sessionI, testMasterClassInfo);
            xpCollectionI.Load();
            xpCollectionI.Reload();

            var listOfTestMaster = sessionI.GetObjects(testMasterClassInfo, new BinaryOperator("Name", "TEST An item with the same key has already been added 1:1", BinaryOperatorType.Equal), null, 0, 0, true, true).OfType <TestMaster>().ToList();

            if (listOfTestMaster.Count > 0)
            {
                tmpTestMaster = listOfTestMaster[0];

                if (tmpTestMaster.Details.Count > 0)
                {
                    tmpString = tmpTestMaster.Details[0].Val;
                }
            }
            #endif

            #if TEST_An_item_with_the_same_key_has_already_been_added
            var listOfTestMaster = sessionI.GetObjects(testMasterClassInfo, new BinaryOperator("Name", "TEST An item with the same key has already been added 1:N", BinaryOperatorType.Equal), null, 0, 0, true, true).OfType <TestMaster>().ToList();

            if (listOfTestMaster.Count > 0)
            {
                tmpTestMaster = listOfTestMaster[0];
                tmpString     = tmpTestMaster.DetailVal;
            }
            #endif

            #if TEST_CREATE
            if ((tmpTestMaster = testMasterClassInfo.CreateNewObject(sessionI) as TestMaster) != null)
            {
                tmpTestMaster.Name = DateTime.Now.Ticks.ToString();

                tmpTestMaster.Details.AddRange(new[]
                {
                    testDetailClassInfo.CreateNewObject(sessionI) as TestDetail,
                    testDetailClassInfo.CreateNewObject(sessionI) as TestDetail,
                    testDetailClassInfo.CreateNewObject(sessionI) as TestDetail
                });

                tmpTestMaster.Details.ToList().ForEach(item => item.Name = DateTime.Now.Ticks.ToString());

                sessionI.Save(tmpTestMaster);
            }
            #endif

            #if TEST_SET
            tmpTestMaster = sessionI.GetObjectByKey <TestMaster>(1L);
            tmpInt        = tmpTestMaster.Details.Count;

            sessionII              = new Session();
            tmpTestMasterII        = sessionII.GetObjectByKey <TestMaster>(2L);
            tmpTestDetailII        = sessionII.GetObjectByKey <TestDetail>(2L);
            tmpTestDetailII.Master = tmpTestMasterII;
            sessionII.Save(tmpTestDetailII);

            tmpInt = tmpTestMaster.Details.Count;
            #endif

            #if TEST_REMOVE
            tmpTestMaster = sessionI.GetObjectByKey <TestMaster>(1L);
            tmpInt        = tmpTestMaster.Details.Count;

            sessionII       = new Session();
            tmpTestMasterII = sessionII.GetObjectByKey <TestMaster>(1L);
            tmpTestDetailII = sessionII.GetObjectByKey <TestDetail>(2L);
            tmpTestMasterII.Details.Remove(tmpTestDetailII);
            sessionII.Save(new XPCustomObject[] { tmpTestMasterII, tmpTestDetailII });

            tmpInt = tmpTestMaster.Details.Count;
            #endif
        }
Пример #2
0
        static void Main(string[] args)
        {
            try
            {
                XpoDefault.ConnectionString = MSSqlConnectionProvider.GetConnectionString(".", "sa", "123", "testdb");
                //XpoDefault.ConnectionString = MSSqlConnectionProvider.GetConnectionString(".", "testdb");

                using (var unitOfWork = new UnitOfWork())
                {
                                        #if TEST_UOW_EVENTS
                    AddEventsListeners(unitOfWork);
                                        #endif

                    TestDE
                        testDE,
                        testDEII;

                                        #if TEST_UOW_EVENTS
                    testDE = new TestDE(unitOfWork);
                    AddEventsListeners(testDE);
                    testDE.f1 = int.MaxValue;
                    testDE.Save();
                    unitOfWork.Save(testDE);
                    unitOfWork.CommitChanges();
                                        #endif

                    long id;

                                        #if TEST_NESTED_UOW
                    TestMaster testMaster;

                                                #if TEST_NESTED_UOW_WITH_NEW
                    testMaster      = new TestMaster(unitOfWork);
                    testMaster.Name = "NewTestMaster";
                    testMaster.Details.Add(new TestDetail(unitOfWork));
                    testMaster.Details.Add(new TestDetail(unitOfWork));
                    testMaster.Details.Add(new TestDetail(unitOfWork));
                    testMaster.Details[0].Name = "NewTestDetail# 0";
                    testMaster.Details[1].Name = "NewTestDetail# 1";
                    testMaster.Details[2].Name = "NewTestDetail# 2";
                                                #else
                    id         = 1;
                    testMaster = unitOfWork.FindObject <TestMaster>(CriteriaOperator.Parse("Id = ?", id));
                                                #endif

                    if (testMaster != null)
                    {
                        testMaster.Details.CollectionChanged += CollectionOnCollectionChanged;
                        testMaster.Details.ListChanged       += CollectionOnListChanged;

                        using (var nestedUOW = unitOfWork.BeginNestedUnitOfWork())
                        {
                            var nestedTestMaster = nestedUOW.GetNestedObject(testMaster);

                            Console.WriteLine("testMaster.GetHashCode() = {0}", testMaster.GetHashCode());
                            Console.WriteLine("nestedTestMaster.GetHashCode() = {0}", nestedTestMaster.GetHashCode());
                            Console.WriteLine();

                            var collection = nestedTestMaster.GetMemberValue("Details") as XPCollection <TestDetail>;

                            collection.ListChanged       += CollectionOnListChanged;
                            collection.CollectionChanged += CollectionOnCollectionChanged;

                            Console.WriteLine("unitOfWork\ttestMaster.Details.Count\t= {0}\t(b4 Remove())", testMaster.Details.Count);
                            Console.WriteLine("nestedUOW\tnestedTestMaster.Details.Count\t= {0}\t(b4 Remove())", nestedTestMaster.Details.Count);
                            Console.WriteLine("nestedUOW\tcollection.Count\t\t= {0}\t(b4 Remove())", collection.Count);
                            Console.WriteLine("Remove()");
                            //collection.Remove(testMaster.Details[0]); // doesn't work
                            //collection.Remove(nestedTestMaster.Details[0]);
                            collection.Remove(collection[0]);
                            Console.WriteLine("nestedUOW\tcollection.Count\t\t= {0}\t(after Remove())", collection.Count);
                            Console.WriteLine("nestedUOW\tnestedTestMaster.Details.Count\t= {0}\t(after Remove())", nestedTestMaster.Details.Count);
                            Console.WriteLine("unitOfWork\ttestMaster.Details.Count\t= {0}\t(after Remove())", testMaster.Details.Count);
                            Console.WriteLine();

                                                                #if TEST_NESTED_UOW_2
                            using (var nestedUOW2 = nestedUOW.BeginNestedUnitOfWork())
                            {
                                var nestedTestMaster2 = nestedUOW2.GetNestedObject(nestedTestMaster);

                                Console.WriteLine("testMaster.GetHashCode() = {0}", testMaster.GetHashCode());
                                Console.WriteLine("nestedTestMaster.GetHashCode() = {0}", nestedTestMaster.GetHashCode());
                                Console.WriteLine("nestedTestMaster2.GetHashCode() = {0}", nestedTestMaster2.GetHashCode());
                                Console.WriteLine();

                                var collection2 = nestedTestMaster2.GetMemberValue("Details") as XPCollection <TestDetail>;

                                collection2.ListChanged       += CollectionOnListChanged;
                                collection2.CollectionChanged += CollectionOnCollectionChanged;

                                Console.WriteLine("unitOfWork\ttestMaster.Details.Count\t= {0}\t(b4 Remove())", testMaster.Details.Count);
                                Console.WriteLine("nestedUOW\tnestedTestMaster.Details.Count\t= {0}\t(b4 Remove())", nestedTestMaster.Details.Count);
                                Console.WriteLine("nestedUOW2\tnestedTestMaster2.Details.Count\t= {0}\t(b4 Remove())", nestedTestMaster2.Details.Count);
                                Console.WriteLine("nestedUOW\tcollection.Count\t\t= {0}\t(b4 Remove())", collection.Count);
                                Console.WriteLine("nestedUOW2\tcollection2.Count\t\t= {0}\t(b4 Remove())", collection2.Count);
                                Console.WriteLine("Remove()");
                                //collection2.Remove(testMaster.Details[0]); // doesn't work
                                //collection2.Remove(nestedTestMaster.Details[0]);  // doesn't work
                                //collection2.Remove(nestedTestMaster2.Details[0]);
                                collection2.Remove(collection2[0]);
                                Console.WriteLine("nestedUOW2\tcollection2.Count\t\t= {0}\t(after Remove())", collection2.Count);
                                Console.WriteLine("nestedUOW\tcollection.Count\t\t= {0}\t(after Remove())", collection.Count);
                                Console.WriteLine("nestedUOW2\tnestedTestMaster2.Details.Count\t= {0}\t(after Remove())", nestedTestMaster2.Details.Count);
                                Console.WriteLine("nestedUOW\tnestedTestMaster.Details.Count\t= {0}\t(after Remove())", nestedTestMaster.Details.Count);
                                Console.WriteLine("unitOfWork\ttestMaster.Details.Count\t= {0}\t(after Remove())", testMaster.Details.Count);
                                Console.WriteLine();

                                Console.WriteLine("unitOfWork\ttestMaster.Details.Count\t= {0}\t(b4 CommitChanges())", testMaster.Details.Count);
                                Console.WriteLine("nestedUOW\tnestedTestMaster.Details.Count\t= {0}\t(b4 CommitChanges())", nestedTestMaster.Details.Count);
                                Console.WriteLine("nestedUOW2\tnestedTestMaster2.Details.Count\t= {0}\t(b4 CommitChanges())", nestedTestMaster2.Details.Count);
                                Console.WriteLine("nestedUOW\tcollection.Count\t\t= {0}\t(b4 CommitChanges())", collection.Count);
                                Console.WriteLine("nestedUOW2\tcollection2.Count\t\t= {0}\t(b4 CommitChanges())", collection2.Count);
                                Console.WriteLine("CommitChanges()");
                                nestedUOW2.CommitChanges();
                                Console.WriteLine("nestedUOW2\tcollection2.Count\t\t= {0}\t(after CommitChanges())", collection2.Count);
                                Console.WriteLine("nestedUOW\tcollection.Count\t\t= {0}\t(after CommitChanges())", collection.Count);
                                Console.WriteLine("nestedUOW2\tnestedTestMaster2.Details.Count\t= {0}\t(after CommitChanges())", nestedTestMaster2.Details.Count);
                                Console.WriteLine("nestedUOW\tnestedTestMaster.Details.Count\t= {0}\t(after CommitChanges())", nestedTestMaster.Details.Count);
                                Console.WriteLine("unitOfWork\ttestMaster.Details.Count\t= {0}\t(after CommitChanges())", testMaster.Details.Count);
                                Console.WriteLine();

                                collection2.CollectionChanged -= CollectionOnCollectionChanged;
                                collection2.ListChanged       -= CollectionOnListChanged;
                            }
                                                                #endif

                            Console.WriteLine("unitOfWork\ttestMaster.Details.Count\t= {0}\t(b4 CommitChanges())", testMaster.Details.Count);
                            Console.WriteLine("nestedUOW\tnestedTestMaster.Details.Count\t= {0}\t(b4 CommitChanges())", nestedTestMaster.Details.Count);
                            Console.WriteLine("nestedUOW\tcollection.Count\t\t= {0}\t(b4 CommitChanges())", collection.Count);
                            Console.WriteLine("CommitChanges()");
                            nestedUOW.CommitChanges();
                            Console.WriteLine("nestedUOW\tcollection.Count\t\t= {0}\t(after CommitChanges())", collection.Count);
                            Console.WriteLine("nestedUOW\tnestedTestMaster.Details.Count\t= {0}\t(after CommitChanges())", nestedTestMaster.Details.Count);
                            Console.WriteLine("unitOfWork\ttestMaster.Details.Count\t= {0}\t(after CommitChanges())", testMaster.Details.Count);
                            Console.WriteLine();

                            collection.CollectionChanged -= CollectionOnCollectionChanged;
                            collection.ListChanged       -= CollectionOnListChanged;
                        }

                        Console.WriteLine("unitOfWork testMaster.Details.Count\t= {0}", testMaster.Details.Count);

                        testMaster.Details.CollectionChanged -= CollectionOnCollectionChanged;
                        testMaster.Details.ListChanged       -= CollectionOnListChanged;

                        unitOfWork.RollbackTransaction();
                    }
                                        #endif

                    #if TEST_DUPLICATES
                    var listOfTestDE = new List <TestDE>
                    {
                        new TestDE(unitOfWork, 1, 1, 1),
                        new TestDE(unitOfWork, 2, 2, 2)
                    };

                    listOfTestDE.ForEach(item => item.id = 13);

                    foreach (var obj in listOfTestDE)
                    {
                        var cInfo     = obj.ClassInfo;
                        var key       = cInfo.GetId(obj);
                        var doubleObj = listOfTestDE.FirstOrDefault(o => ReferenceEquals(cInfo, o.ClassInfo) && !ReferenceEquals(obj, o) && Equals(key, cInfo.GetId(o)));
                        if (doubleObj == null)
                        {
                            continue;
                        }

                        System.Diagnostics.Debug.WriteLine("Double is found: key = {0}; ClassInfo = {1}; {2} -> {3}", key, cInfo, obj, doubleObj);
                    }
                    #endif

                    id     = -1;
                    testDE = unitOfWork.GetObjectByKey <TestDE>(id);
                    if (testDE == null)
                    {
                        testDE    = new TestDE(unitOfWork);
                        testDE.id = id;

                        testDEII = unitOfWork.GetObjectByKey <TestDE>(id); // null

                        testDE.Save();
                        testDEII = unitOfWork.GetObjectByKey <TestDE>(id); // null
                    }


                    id = 3;

                    if ((testDE = unitOfWork.FindObject <TestDE>(CriteriaOperator.Parse("id=?", id))) == null)
                    {
                        testDE = new TestDE(unitOfWork, 1, 1, 1);
                        testDE.Save();
                    }

                    testDE.f2 *= 2;

                    id = 4;
                    if ((testDE = unitOfWork.FindObject <TestDE>(CriteriaOperator.Parse("id=?", id))) == null)
                    {
                        testDE = new TestDE(unitOfWork, 1, 1, 1);
                        testDE.Save();
                    }

                    testDE.f2 *= 2;

                    System.Diagnostics.Debug.WriteLine("unitOfWork.BeginNestedUnitOfWork()");

                    using (var nestedUOW = unitOfWork.BeginNestedUnitOfWork())
                    {
                        TestDE
                            nestedTestDE;

                        if ((nestedTestDE = unitOfWork.FindObject <TestDE>(CriteriaOperator.Parse("id=?", id))) == null)
                        {
                            nestedTestDE = new TestDE(nestedUOW, 1, 1, 1);
                            nestedTestDE.Save();
                        }

                        Console.WriteLine(testDE.ToString());

                        nestedTestDE.f3 *= 3;

                        Console.WriteLine(testDE.ToString());

                        nestedUOW.CommitChanges();
                        System.Diagnostics.Debug.WriteLine("nestedUOW.CommitChanges()");
                    }

                    unitOfWork.CommitChanges();

                    #if TEST_UOW_EVENTS
                    RemoveEventsListeners(unitOfWork);
                    #endif
                }
            }
            catch (Exception eException)
            {
                Console.WriteLine(eException.GetType().FullName + Environment.NewLine + "Message: " + eException.Message + Environment.NewLine + (eException.InnerException != null && !string.IsNullOrEmpty(eException.InnerException.Message) ? "InnerException.Message" + eException.InnerException.Message + Environment.NewLine : string.Empty) + "StackTrace:" + Environment.NewLine + eException.StackTrace);
            }
        }