I am using CSLA 2.1 with my client Windows XP SP2 at home and my data located on a decdicated server at the hosting service location.
When I save the root object all is fine but when I try to open a second connection for saving the child collection I get the following error on the cn.Open() statement.
3:53:11 PM: MTGOSession 0: MTGOTraderController:TradePerformed Exception:DataPortal.Update failed (System.Transactions.TransactionException: The partner transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D025) ---> System.Runtime.InteropServices.COMException (0x8004D025): The partner transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D025)
I was able to insert the root using the TransactionType.TransactionScope setting. I am able to also update the root object. Seem all is related to the child objects Insert method. Any ideas? I am guess that MSDTC isn't talking through the fire walls correctly. I check the MSDTC settings on the server an my client and all seems to be setup correctly.
Here is the root Portal_Update code, the child collections Update methods and the child object insert method.
[
Transactional(TransactionalTypes.TransactionScope)] protected override void DataPortal_Update(){
// TODO: update values if (base.IsDirty){
using (SqlConnection cn = new SqlConnection(Database.ApplicationConnection)){
cn.Open();
using (SqlCommand cm = cn.CreateCommand()){
cm.CommandText =
"updateTrade";cm.Parameters.AddWithValue(
"@SDTradeID", _SDTradeID);cm.Parameters.AddWithValue(
"@LastChanged", _timestamp); SqlParameter param;param =
new SqlParameter("@DateUpdated", SqlDbType.DateTime);param.Direction =
ParameterDirection.Output;cm.Parameters.Add(param);
DoInsertUpdate(cm);
// Get output parameters_DateUpdated =
new SmartDate((DateTime)(cm.Parameters["@DateUpdated"].Value));}
}
}
// update child objects_TradeItemsDealer.Update(
this);_TradeItemsTrader.Update(
this);}
internal void Update(BOTrade Trade)
{
this.RaiseListChangedEvents = false; // update (thus deleting) any deleted child objects foreach (BOTradeItem obj in DeletedList){
obj.DeleteSelf(Trade);
}
// now that they are deleted, remove them from memory tooDeletedList.Clear();
// add/update any current child objects foreach (BOTradeItem obj in this){
if (obj.IsNew){
obj.Insert(Trade);
}
else{
obj.Update(Trade);
}
}
this.RaiseListChangedEvents = true;}
[
Transactional(TransactionalTypes.TransactionScope)] internal void Insert(BOTrade Trade){
// if we're not dirty then don't update the database if (!this.IsDirty){
return;}
using (SqlConnection cn = new SqlConnection(Database.ApplicationConnection)){
cn.Open();
using (SqlCommand cm = cn.CreateCommand()){
cm.CommandText =
"addTradeItem"; // Setup to get back identity column SqlParameter param = new SqlParameter("@SDTradeItemID", SqlDbType.Int);param.Direction =
ParameterDirection.Output;cm.Parameters.Add(param);
cm.Parameters.AddWithValue(
"@SDTradeID", _SDTradeID);cm.Parameters.AddWithValue(
"@SDAccountID", _SDAccountID);cm.Parameters.AddWithValue(
"@MTGOAccountID", _MTGOAccountID);cm.Parameters.AddWithValue(
"@MTGOAccountName", _MTGOAccountName);cm.Parameters.AddWithValue(
"@InventoryCode", _InventoryCode);cm.Parameters.AddWithValue(
"@DateCreated", _DateCreated.DBValue);DoInsertUpdate(cm);
// Get identity_SDTradeItemID = (
int)cm.Parameters["@SDTradeItemID"].Value;MarkOld();
}
}
}
That is just the way the example project does it. It opens seperate connection objects for the root and then does it again for the children.
Since I posted this I found a work around that was discuss in one of th topics on this site.
That is to pass down the connection object and not to open a new one, like how transaction objects were pass down to child objects in CSLA 1.0 and reused.
so now I say childList.Update(this, cn) passing the root object and the connection object.
Seems opening the second connection object kicks in the MSDTC and seems I either don't have something configured correctly or my firewall is interfering.
Thanks.
Copyright (c) Marimer LLC