This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
Hi, I am having an issue when trying to access a related entity which has been lazy loaded. Each time I try and access the related entity I get the exception " Can Not Access Disposed Object " Each time I tried uploading my project IE stopped responding, so I have added the data access bits below. My Unit of work is generated using the class below public class AppContext
{
private static readonly LightSpeedContext
} I have a data class (to keep my data and UI separate) and my dataclass called AccountDataAccess (which implements IDisposable) I access the unit of work as shown using (var uow = Model.AppContext.UnitOfWork)
{
result = uow.FindById I access the AccountDataAccess class via an interface Account currentAccount=Factory.CreateAccountData().FetchAccountById(Int32 id); After retrieving the above Account entity and try accessing a child entity I get the exception. Cheers and thank you in advance. |
|
|
This will be occurring because you are loading the parent entity from a UnitOfWork which is being disposed prior to you performing the lazy load. You are loading your initial entity and then immediately disposing the UnitOfWork because of the using scope - e.g.
The UnitOfWork instance is still associated with result because result has not been detached. So later on when you attempt to touch one of its unloaded associations this triggers a lazy load. This then attempts to perform the load using the associated UnitOfWork which is disposed which leads to the exception. To avoid this you will either need to change how you are handling your UnitOfWork scoping, or look at using eager loading or a combination of the two. I would start by looking at your scoping. Generally you want a scope which is narrow enough to avoid being long lived but wide enough to complete all queries and persistance operations to cover the current function you are trying to perform. In the code block above does Model.AppContext.UnitOfWork return a new UnitOfWork instance for each access? If not you may be inadvertently disposing this via the use of the using statement. Is this a web application? If so you may want to look at scoping your UnitOfWork on a per request basis instead.
|
|
|
Jeremy, Thankyou for your reponse. This is a windows app I am putting together to become familiar with Lightspeed and the best way to use it. Do you have a quick example of how I should use the unit of work in this kind of scenario. I had a look at the samples but could not find a scenario close to how I am structuring the application. The structure they use here is as follows. Data.Factory (contains a static method to return an instance of the AccountData object found below) i.e. public static IAccountData CreateAccountData()
{ Data.Factory.SQL (here is where the domain model would site) as well as the context to create the unit of work the UI calls a method like the following to return an account Data.Factory.CreateaccountData().FetchAccountById(1000); Thankyou, your help is much appreciated, I have enjoyed LightSpeed in the week I have been using it. Cheers |
|
|
Generally for a Windows app you are likely to need to use a longer running UnitOfWork because presumably you want to fetch entities, bind them to a UI and then allow them to be manipulated and updated over a reasonable period of actual time. You will certainly need to scope wider than you currently are to solve your current problem of lazy loading. So generally unless you need multiple connections to the database you will want to have a globally available object which mediates access to a UnitOfWork for you which can control its lifetime - e.g. using a Repository pattern or injecting and scoping the lifetime of a UnitOfWork instance via an IoC container but thats probably better decided by you. It looks like you are using a Repository style at the moment, so one quick way of keeping the UnitOfWork longer living is have it instantiated and managed by the Factory class and then pass it as an argument into the constructor of your AccountData instance. As an aside have you had a read through the documentation around building WPF and Windows Forms applications with LightSpeed? If not you can peruse this online here: http://www.mindscapehq.com/documentation/lightspeed/Building-WPF-and-Windows-Forms-Applications-
|
|