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, We are trying to build a system against an Oracle database with multiple schema's. Our General schema contains setting data, parameter data etc. Our Domain schemas contain our domain specific data. In our controllerbase class we create our General unit of work scope and our domains unit of work scopes: generalUnitOfWorkScope = new PerRequestUnitOfWorkScope<EAGeneralUnitOfWork>(MvcApplication.SMSEAGeneralLightSpeedContext); electricityUnitOfWorkScope = new PerRequestUnitOfWorkScope<EADomainUnitOfWork>(MvcApplication.SMSEAElectricityLightSpeedContext); gasUnitOfWorkScope = new PerRequestUnitOfWorkScope<EADomainUnitOfWork>(MvcApplication.SMSEAGasLightSpeedContext); In our controller constructor code we now wish to first retrieve data from the general schema: GenericService = new GenericDataService(new ModelStateWrapper(ModelState), new GenericRepository(GeneralUnitOfWorkScope)); fill a list: Domains = GenericService.GetDomains(); and later on in our Controller.Action code: MpService = new MeteringPointService(new ModelStateWrapper(ModelState),new OperationsRepository(ElectricityUnitOfWorkScope)); and fill a list in our model: model.ConnectionData = MpService.GetConnections(currentPageIndex, DefaultPageSize, ref totalCount); The first GenericService call retrieves the data without problems. However when trying to get domain specific data, I get an error. I have the feeling that this is caused by the PerRequestUnitOfWorkScope that must be used for web apps. the error is (sorry for the Dutch OS, but niet=not and converteren=convert ;) ) : base {System.Exception} = {"Kan een object van het type SMS.EBA.EA.Model.General.EAGeneralUnitOfWork niet converteren naar het type SMS.EBA.EA.Model.EADomainUnitOfWork."} Even though I am now in my Action code, LS appears to have "cached" the previously used uowscope in my controller constructor and now tries to cast the uowscope that was created the first to the current. (that came out nicely :( I hope you understand this part! In short (that always means that the story is too long): How can I connect to 2 different models/database connections in 1 controller? I tried to pull the unitofworkscope bit out of the controllerbase and create it where I need it (in the Action or in the constructor) but that did not help. Best regards,
|
|
|
Hi Richard :) Your assumption is correct - the first scope you have fetched using PerRequestUnitOfWorkScope.Current causes a value to be stored in a HttpContext.Current.Items[] key. The next time this is accessed (from a different UOW type) you will get the casting exception, as it will try and pull this value out of .Items and cast it according to your generic typing. This is just down to the implementation of PerRequestUnitOfWorkScope, so in your case I think it would be better to set up your own UOWScope container which can cache your various UOW's accordingly - the PerRequest one is working on the assumption you only have one type of UOW. If you implement UnitOfWorkScopeBase, here is the implementation for .Current of the PerRequest version: public override TUnitOfWork Current { get { var current = (TUnitOfWork)HttpContext.Current.Items[ItemsKey]; if (current == null) { HttpContext.Current.Items[ItemsKey] = current = LightSpeedContext.CreateUnitOfWork(); } return current; } }
If you just used this same approach but had the ItemsKey (which is just a constant in PerRequest) seeded with some value derived from TUnitOfWork (e.g. perhaps the type name), then you should be able to accomodate multiple UOWs happily enough :) Let us know how you get on - if this works well then we can roll it back into the framework proper.
Cheers! Jeremy |
|
|
Thanks Jeremy! We tried this and it works with simple fetch functions. We'll test a bit more and post the code
Cheers,
Richard |
|
|
Jeremy, This is what we eventually ended up with, we took the liberty to already put the code in the Mindscape.Lightspeed namespace ;): using System.Web; namespace Mindscape.LightSpeed } public PerRequestMultipleUnitOfWorkScope(LightSpeedContext<TUnitOfWork> lightSpeedContext, string customKey) private string CustomKey public override TUnitOfWork Current } return current; public override bool HasCurrent You probably noticed the additional constructor with customKey. Because we have the situation where we have 2 database schema's with the exact same single LS model, we needed the additional constructor with a custom key string. This is done to cater for the situation where we want to access both database schemas during 1 request. The uowscope types would in this case be exactly identical and retrieving the "current" based on type would not necessarily return the expected database connection. So we needed a way to distinguish "what schema we would like to access in a workscope". You guys determine if this is what you would like to have this in the framework as well... We put this class in our solution for now and it works like a charm, also transactions on 2 workscopes/database schemas work satisfactorily. Thanks so much for the great support and responsiveness (even though I think you guys should have multiple shifts for each time zone ;P) Best regards,
Richard
|
|
|
Thanks for the update Richard :) And much appreciated for sharing your solution back! We will have a review of this for including it back into the core :)
Cheers, Jeremy |
|