public void CreateChildTransactionMode_WithNonLoadableOutParameter()
        {
            ExecuteDelegateInWxeFunction(
                WxeTransactionMode <ClientTransactionFactory> .CreateRoot,
                (parentCtx, parentF) =>
            {
                var subFunction = new DomainObjectParameterTestTransactedFunction(
                    WxeTransactionMode <ClientTransactionFactory> .CreateChildIfParent,
                    (ctx, f) =>
                {
                    f.OutParameter      = SampleObject.NewObject();
                    f.OutParameterArray = new[] { SampleObject.NewObject() };
                },
                    null,
                    null);

                subFunction.SetParentStep(parentF);
                subFunction.Execute(parentCtx);

                var parentTransaction = parentF.Transaction.GetNativeTransaction <ClientTransaction>();
                Assert.That(parentTransaction.IsEnlisted(subFunction.OutParameter), Is.True);
                Assert.That(subFunction.OutParameter.State, Is.EqualTo(StateType.Invalid));
                Assert.That(() => subFunction.OutParameter.EnsureDataAvailable(), Throws.TypeOf <ObjectInvalidException>());

                Assert.That(parentTransaction.IsEnlisted(subFunction.OutParameterArray[0]), Is.True);
                Assert.That(subFunction.OutParameterArray[0].State, Is.EqualTo(StateType.Invalid));
                Assert.That(() => subFunction.OutParameterArray[0].EnsureDataAvailable(), Throws.TypeOf <ObjectInvalidException>());
            });
        }
        public void CreateChildTransactionMode_WithNonLoadableInParameter()
        {
            ExecuteDelegateInWxeFunction(
                WxeTransactionMode <ClientTransactionFactory> .CreateRoot,
                (parentCtx, parentF) =>
            {
                var inParameter = SampleObject.NewObject();
                inParameter.Delete();

                var inParameterArray = new[] { SampleObject.NewObject() };
                inParameterArray[0].Delete();

                var subFunction = new DomainObjectParameterTestTransactedFunction(
                    WxeTransactionMode <ClientTransactionFactory> .CreateChildIfParent,
                    (ctx, f) =>
                {
                    Assert.That(f.InParameter.State, Is.EqualTo(StateType.Invalid));
                    Assert.That(() => f.InParameter.EnsureDataAvailable(), Throws.TypeOf <ObjectInvalidException> ());

                    Assert.That(f.InParameterArray[0].State, Is.EqualTo(StateType.Invalid));
                    Assert.That(() => f.InParameterArray[0].EnsureDataAvailable(), Throws.TypeOf <ObjectInvalidException> ());
                },
                    inParameter,
                    inParameterArray);

                subFunction.SetParentStep(parentF);
                subFunction.Execute(parentCtx);
            });
        }
        public void CreateChildTransactionMode_InAndOutParametersCanBeUsed()
        {
            ExecuteDelegateInWxeFunction(
                WxeTransactionMode <ClientTransactionFactory> .CreateRoot,
                (parentCtx, parentF) =>
            {
                var inParameter                   = SampleObject.NewObject();
                var inParameterArray              = new[] { SampleObject.NewObject() };
                inParameter.Int32Property         = 7;
                inParameterArray[0].Int32Property = 8;

                var parentTransaction = parentF.Transaction.GetNativeTransaction <ClientTransaction> ();

                var subFunction = new DomainObjectParameterTestTransactedFunction(
                    WxeTransactionMode <ClientTransactionFactory> .CreateChildIfParent,
                    (ctx, f) =>
                {
                    var clientTransaction = f.Transaction.GetNativeTransaction <ClientTransaction> ();
                    Assert.That(clientTransaction, Is.Not.Null.And.SameAs(ClientTransaction.Current));
                    Assert.That(clientTransaction, Is.Not.SameAs(parentTransaction));
                    Assert.That(clientTransaction.ParentTransaction, Is.SameAs(parentTransaction));

                    Assert.That(clientTransaction.IsEnlisted(f.InParameter), Is.True);
                    Assert.That(clientTransaction.IsEnlisted(f.InParameterArray[0]));

                    // Since this function is running in a subtransaction, the properties set in the parent transaction are visible from here.
                    Assert.That(f.InParameter.Int32Property, Is.EqualTo(7));
                    Assert.That(f.InParameterArray[0].Int32Property, Is.EqualTo(8));

                    // Since this function is running in a subtransaction, out parameters are visible within the parent function if the transaction is
                    // committed.
                    f.OutParameter = SampleObject.NewObject();
                    f.OutParameter.Int32Property         = 17;
                    f.OutParameterArray                  = new[] { SampleObject.NewObject(), SampleObject.NewObject() };
                    f.OutParameterArray[0].Int32Property = 4;

                    ClientTransaction.Current.Commit();

                    f.OutParameterArray[1].Int32Property = 5;
                },
                    inParameter,
                    inParameterArray);

                subFunction.SetParentStep(parentF);
                subFunction.Execute(parentCtx);

                var outParameter      = subFunction.OutParameter;
                var outParameterArray = subFunction.OutParameterArray;

                Assert.That(parentTransaction.IsEnlisted(outParameter), Is.True);
                Assert.That(outParameter.Int32Property, Is.EqualTo(17));
                Assert.That(parentTransaction.IsEnlisted(outParameterArray[0]), Is.True);
                Assert.That(outParameterArray[0].Int32Property, Is.EqualTo(4));
                Assert.That(parentTransaction.IsEnlisted(outParameterArray[1]), Is.True);
                Assert.That(outParameterArray[1].Int32Property, Is.Not.EqualTo(4));
            });
        }
        public void CreateNoneTransactionMode_FunctionCanUseObjectsFromOuterTransaction()
        {
            using (ClientTransaction.CreateRootTransaction().EnterDiscardingScope())
            {
                var outerTransaction = ClientTransaction.Current;

                var inParameter      = SampleObject.NewObject();
                var inParameterArray = new[] { SampleObject.NewObject() };
                inParameter.Int32Property         = 7;
                inParameterArray[0].Int32Property = 8;

                SampleObject   outParameter;
                SampleObject[] outParameterArray;
                ExecuteDelegateInWxeFunctionWithParameters(WxeTransactionMode <ClientTransactionFactory> .None, (ctx, f) =>
                {
                    var clientTransaction1 = f.Transaction.GetNativeTransaction <ClientTransaction> ();
                    Assert.That(clientTransaction1, Is.Null);
                    Assert.That(ClientTransaction.Current, Is.SameAs(outerTransaction));

                    Assert.That(outerTransaction.IsEnlisted(f.InParameter), Is.True);
                    Assert.That(outerTransaction.IsEnlisted(f.InParameterArray[0]));

                    Assert.That(f.InParameter.Int32Property, Is.EqualTo(7));
                    Assert.That(f.InParameterArray[0].Int32Property, Is.EqualTo(8));

                    f.OutParameter = DomainObjectIDs.ClassWithAllDataTypes1.GetObject <SampleObject> ();
                    f.OutParameter.Int32Property = 12;

                    f.OutParameterArray = new[] { DomainObjectIDs.ClassWithAllDataTypes2.GetObject <SampleObject> () };
                    f.OutParameterArray[0].Int32Property = 13;
                }, inParameter, inParameterArray, out outParameter, out outParameterArray);

                // Since everything within the function occurred in the same transaction that called the function, all enlisted objects are the same
                // and all changes are visible after the function call.
                Assert.That(ClientTransaction.Current.IsEnlisted(outParameter), Is.True);
                Assert.That(outParameter.Int32Property, Is.EqualTo(12));

                Assert.That(ClientTransaction.Current.IsEnlisted(outParameterArray[0]), Is.True);
                Assert.That(outParameterArray[0].Int32Property, Is.EqualTo(13));
            }
        }
        public void SetUp()
        {
            try
            {
                var providers = new ProviderCollection <StorageProviderDefinition>();
                providers.Add(new RdbmsProviderDefinition("TheStorageProvider", new SqlStorageObjectFactory(), TestDomainConnectionString));
                var storageConfiguration = new StorageConfiguration(providers, providers["TheStorageProvider"]);

                DomainObjectsConfiguration.SetCurrent(new FakeDomainObjectsConfiguration(storage: storageConfiguration));

                SqlConnection.ClearAllPools();

                var scriptGenerator = new ScriptGenerator(
                    pd => pd.Factory.CreateSchemaScriptBuilder(pd),
                    new RdbmsStorageEntityDefinitionProvider(),
                    new ScriptToStringConverter());
                var scripts = scriptGenerator.GetScripts(MappingConfiguration.Current.GetTypeDefinitions()).Single();

                var masterAgent = new DatabaseAgent(MasterConnectionString);
                masterAgent.ExecuteBatchFile("Database\\CreateDB.sql", false, DatabaseConfiguration.GetReplacementDictionary());

                var databaseAgent = new DatabaseAgent(TestDomainConnectionString);
                databaseAgent.ExecuteBatchString(scripts.SetUpScript, true);

                using (ClientTransaction.CreateRootTransaction().EnterDiscardingScope())
                {
                    DomainObjectIDs.ClassWithAllDataTypes1 = SampleObject.NewObject().ID;
                    DomainObjectIDs.ClassWithAllDataTypes2 = SampleObject.NewObject().ID;
                    ClientTransaction.Current.Commit();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("SetUpFixture failed: " + e);
                Console.WriteLine();
                throw;
            }
        }