In my current project I'm trying to have a local copy of the remote database stored on the user's computer so in the event that a customer loses internet, they still have access to their data and can create/update data while offline. The database schemas between remote and local are the exact same so we really shouldn't NEED a new model to have two PersistenceManagers going to each, however, what we've tried so far has not worked. Currently, we create the main PersistenceManager that points to the remote database, then we initialize the second PersistenceManager to point to the local database, so far here's what we've tried:
- Manually creating a new RdbKey for the LocalDB instance in the IdeaBlade.ibconfig
- Using the Object Mapper to create the RdbKey for the LocalDB instance
- Altering the default RdbKey to point to the local database after initializing the main PersistenceManager
What I've found doing all three of these different tasks was the same error.
Error No datasource key found for this entity type
Stack Trace at IdeaBlade.Persistence.PersistenceManager.HandlePersistenceServerException(Exception pException, Boolean pTryToHandle, PersistenceOperation pOperation)
at IdeaBlade.Persistence.PersistenceManager.XFetchDataSet(IEntityQuery pEntityQuery)
at IdeaBlade.Persistence.PersistenceManager.XFetch(IEntityFinder pEntityFinder, WorkState pWorkState)
at IdeaBlade.Persistence.PersistenceManager.XGetEntities(IEntityQuery pEntityQuery, QueryStrategy pQueryStrategy, WorkState pWorkState)
at IdeaBlade.Persistence.PersistenceManager.GetEntities[T](IEntityQuery pEntityQuery, QueryStrategy pQueryStrategy)
at SQLEmbeddedTesting.Form1.simpleButton1_Click(Object sender, EventArgs e) in c:\users\dev2\source\repos\SQLEmbeddedTesting\SQLEmbeddedTesting\Form1.cs:line 59
Inner Exception Number IdeaBlade.Util.IdeaBladeException: No datasource key found for this entity type
at IdeaBlade.Persistence.Wcf.WcfPersistenceServerProxy.CheckConnection(Exception pException)
at IdeaBlade.Persistence.PersistenceServerProxy.Fetch(SessionBundle pBundle, IEntityQuery pQuery)
at IdeaBlade.Persistence.PersistenceManager.XFetchDataSet(IEntityQuery pEntityQuery)
Date Time: 7/25/2018 1:27:42 PM
Is there something that I'm doing wrong here or is there something special I need to do to get this to work. The only way I've found to get this to work is by creating two separate keys in the Object Mapper, and creating two mirrored models for the two PersistenceManagers to connect to. However, that's hugely inefficient for what we're trying to do.
Here's the code I'm currently using to attempt this:
IdeaBladeConfig config = IdeaBladeConfig.Instance;
config.Remoting.RemotePersistenceEnabled = false;
config.Remoting.RemoteBaseUrl = "SERVER_URL";
mPersMgr = new PersistenceManager(false);
mPersMgr.Connect();
config.Remoting.RemotePersistenceEnabled = false;
config.Remoting.RemoteBaseUrl = "127.0.0.1";
localPersMgr = new PersistenceManager(false, "default", PersistenceServiceOption.UseLocalService);
localPersMgr.Connect();
EntityList<Addresses> mainList = new EntityList<Addresses>();
EntityList<Addresses> localList = new EntityList<Addresses>();
RdbQuery query = new RdbQuery(typeof(Addresses));
mainList.ReplaceRange(mPersMgr.GetEntities<Addresses>(query, QueryStrategy.DataSourceOnly));
localList.ReplaceRange(localPersMgr.GetEntities<Addresses>(query, QueryStrategy.DataSourceOnly));
You can accomplish this using data source key extensions. You only need your one Object Mapper model - let's say it uses a data source name of "default". In your ibconfig (or app.config) you do want two RdbKeys - but with different extensions. So for example:
When you create the PersistenceManager you need to indicate which extension to use, along with the "PersistenceServiceOption". This option tells the PM whether to look at the remoting info in the config file or ignore it. So for example:
The
PersistenceServiceOption.UseDefaultServiceoption indicates it should use theremotePersistenceEnabledsetting in the config; you could also useUseRemoteServiceif you know you will always point to a BOS.You shouldn't be changing IdeaBladeConfig.Instance information in code, other than any initial setup information you might want to do.
If you're using a DataSourceKeyResolver to build up RdbKeys the process is similar. Use the data source extension to differentiate the connection string and RdbKey built.
Also, make sure you double check anywhere you might be looking at RdbKeys - for example in a custom IdGenerator which tests data source applicability - to ensure your code handles the extensions correctly.