ContextManager.GetManager(..): use another DataContext while accesing a DataContext

ContextManager.GetManager(..): use another DataContext while accesing a DataContext

Old forum URL: forums.lhotka.net/forums/t/11123.aspx


Troncho posted on Thursday, February 02, 2012

Hi everybody. I've come across an issue regarding the use of CSLA ContextManager.

I have several DataContexts with different tables / sp each.

In my case, I have a particular problem during the DataPortal_Fetch<..> operation.

I have a class that manages Vendor Bills, which includes an BusinessObject child reference to a Currency object having information about the currency, exchange rate, ... used for each bill.

public class VendorBill : BusinessBase<VendorBill>
{

....

		private static PropertyInfo<Guid> CurrencyIdProperty = RegisterProperty<Guid>(c => c.CurrencyId);
		public Guid CurrencyId
		{
			get { return CurrencyObj.Id; }
			set
			{
				LoadProperty(CurrencyObjProperty, CurrencyBase.GetCurrencyBase(value));
				PropertyHasChanged("CurrencyObj");
			}
		}
 
		// CurrencyObj...
		private static PropertyInfo<CurrencyBase> CurrencyObjProperty =
			RegisterProperty<CurrencyBase>(p => p.CurrencyObj);
		public CurrencyBase CurrencyObj
		{
			get
			{
				// Lazy loading...
				if (!(FieldManager.FieldExists(CurrencyObjProperty)))
					LoadProperty(CurrencyObjProperty, CurrencyBase.GetCurrencyBase());
 
				return GetProperty(CurrencyObjProperty);
			}
		}
....
 
// Data access...
		private void DataPortal_Fetch(SingleCriteria<VendorBill, Guid> criteria)
		{
			using (var ctx =
				ContextManager<NrgNet.DalLinq.AP.APDataContext>.GetManager(Erp.DalLinq.Database.Erp))
			{
				var data = (from p in ctx.DataContext.VendorBills
										where p.BillId == criteria.Value
										select p).Single();
...
					// This will call CurrencyId -> Set
					CurrencyId = data.CurrencyId;
...
 
			}
 
		}
...
}
 
 
And then I have the CurrencyBase class whose DataPortal_Fetch is on a different DataContext...
 
public class CurrencyBase : BusinessBase<CurrencyBase>
{
...
internal static GenMonedaInfoBase GetGenMonedaInfoBase(Guid id)
{
return DataPortal.FetchChild<CurrencyBase>(new SingleCriteria<CurrencyBase, Guid>((Guid)id));
}
 
...
 
		private void Child_Fetch()
		{
			using (var ctx =
				ContextManager<NrgNet.DalLinq.General.GeneralDataContext>.GetManager(Erp.DalLinq.Database.Erp))
			{
				var data = (from p in ctx.DataContext.Currencies
													select p).FirstOrDefault();
 
				if (data == null)
					throw new IndexOutOfRangeException(Resources.DefaultCurrencyDoesntExist);
 
				Child_Fetch(data);
			}
		}
 
		private void Child_Fetch(DalLinq.General.Currencies dalCurrency)
		{
			Id = dalGenMoneda.CurrencyId;
			Info = ...
		}
...
}
 
 
So, when the 2nd ContextManager in the Currencies Class tries to use GetManager, the system throws an exception as I already have a previous ctx open on a different DataContext.
 
This issue will repetedly appear on my App as there are lots of collaborating classes that operate much like this case.
 
Any suggestions will be very appreciated.
 
Thanks in advance :)
 

Troncho replied on Friday, February 03, 2012

Issue solved. I went through

ContextManager<C>.GetManager()
and I found this GetManager(db, label) overload where I can call distinct DataContexts simultaneously.

Something else arouse... When I tried to inherit from ContextManager, I couldn't as it has only a private constructor.
My itention was to re define the method GetManager as
public static new ContextManager<C> GetManager(string db) 
{
string label = typeof(C).Name;
return GetManager(db, label);
}

Any suggestions on how to do this?
Thanx!
Troncho

JonnyBee replied on Friday, February 03, 2012

Hi,

Yes, you are right that ContextManager at current is not supporting subclasses and as such should have been declared as sealed.

 

 

Troncho replied on Saturday, February 04, 2012

Yes, Jonny, I thought the same. Thanx!

Copyright (c) Marimer LLC