This question is locked. New answers and comments are not allowed.
how to develop modules in web application with same connection string id?( Version 2010 Q3)
In previous versions there was no problem.
When using a connection string I get an error.
In previous versions there was no problem.
When using a connection string I get an error.
Type is enhanced and registered, but not available from the database class meta data. This can be caused by a wrong connection id or configuration.Parameter name: srcActual value was3 Answers, 1 is accepted
0
Accepted
Hello alex,
I assume that you are having multiple domain models (perhaps one for each module) that are using the same database and connection string. Unfortunately at the moment this is not possible out of the box. The problem is that once a connection to the database is obtained, OpenAccess creates internally a Database object which associates the opened database with some metadata. In order to use multiple models with the same database you will have to merge the metadata from all models prior to opening the database and pass the merged content when a connection has to be established for the first time. Some sample code that does the metadata merging is shown in this thread.
However, I think it would be easier for you just to use connection strings with different names. This would save you some time for writing code and it will be easier to switch back to a single connection string when OpenAccess supports this scenario, without modifying the code.
Please note that if you need to change the name of the connection string your rlinq file refers to, you will have to open the rlinq using an xml editor and locate the AppConfigConnectionPropertyName tag, it should be under rlinq : Runtime : ModelSettings. This holds the name of the connection string that is retrieved from the application configuration file.
Hope that helps.
Best wishes,
Alexander
the Telerik team
I assume that you are having multiple domain models (perhaps one for each module) that are using the same database and connection string. Unfortunately at the moment this is not possible out of the box. The problem is that once a connection to the database is obtained, OpenAccess creates internally a Database object which associates the opened database with some metadata. In order to use multiple models with the same database you will have to merge the metadata from all models prior to opening the database and pass the merged content when a connection has to be established for the first time. Some sample code that does the metadata merging is shown in this thread.
However, I think it would be easier for you just to use connection strings with different names. This would save you some time for writing code and it will be easier to switch back to a single connection string when OpenAccess supports this scenario, without modifying the code.
Please note that if you need to change the name of the connection string your rlinq file refers to, you will have to open the rlinq using an xml editor and locate the AppConfigConnectionPropertyName tag, it should be under rlinq : Runtime : ModelSettings. This holds the name of the connection string that is retrieved from the application configuration file.
Hope that helps.
Best wishes,
Alexander
the Telerik team
0
alex
Top achievements
Rank 1
answered on 22 Dec 2010, 04:13 PM
Tanks.
Yes. I have multiple domain models in multiple projects. How to
Yes. I have multiple domain models in multiple projects. How to
merge MetaData in any project?0
Hello alex,
The metadata merging has to be done in your main application after all modules have been loaded and before any module has started working with the database. There are two possible cases based on the architecture of your application. I am not sure which of them fits your scenario, so I will give some details for both of them.
If the main application references the modules directly, you can use the exact same code from the thread I mentioned in my previous post.
However, if the main application is not aware of the modules but the modules reference the application, the approach is a bit different. In the application you will have to provide a collection of MetadataContainer objects which can be accessed and populated by each module. This way when a module loads, it will add its metadata to the global list of metadata containers of the application. In this case it is appropriate to use an ObservableCollection object in order to know when new metadata has been added. Below is all the code you may need to achieve this:
Please note that this code would create a new Database instance for each loaded module. You can avoid that if your application is able to determine when all modules have been loaded. In such a case the ObservableCollection<T> object can be substituted with a normal List<T>. I hope that helps.
Best wishes,
Alexander
the Telerik team
The metadata merging has to be done in your main application after all modules have been loaded and before any module has started working with the database. There are two possible cases based on the architecture of your application. I am not sure which of them fits your scenario, so I will give some details for both of them.
If the main application references the modules directly, you can use the exact same code from the thread I mentioned in my previous post.
However, if the main application is not aware of the modules but the modules reference the application, the approach is a bit different. In the application you will have to provide a collection of MetadataContainer objects which can be accessed and populated by each module. This way when a module loads, it will add its metadata to the global list of metadata containers of the application. In this case it is appropriate to use an ObservableCollection object in order to know when new metadata has been added. Below is all the code you may need to achieve this:
public static class OpenAccessHelper { private static ObservableCollection<MetadataContainer> globalContainer; public static ObservableCollection<MetadataContainer> GlobalContainer { get { if (globalContainer == null) { globalContainer = new ObservableCollection<MetadataContainer>(); globalContainer.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(globalContainer_CollectionChanged); } return globalContainer; } } static void globalContainer_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { //dispose the already loaded database object Database cachedDatabase = Database.Get("ConnectionString"); cachedDatabase.Dispose(); //establish a new database connection with the latest metadata Database.Get("ConnectionString", new BackendConfiguration() { Backend = "mssql" }, GetMergedMetadata()); } public static void RegisterMetaContainer(MetadataContainer container) { GlobalContainer.Add(container); } public static MetadataContainer GetMergedMetadata() { MetadataContainer metadata = new MetadataContainer(); foreach(MetadataContainer container in GlobalContainer) { MergeMetaItems(metadata.PersistentTypes, container.PersistentTypes); MergeMetaItems(metadata.Tables, container.Tables); MergeMetaItems(metadata.Views, container.Views); MergeMetaItems(metadata.StoredProcedures, container.StoredProcedures); MergeMetaItems(metadata.Constraints, container.Constraints); MergeMetaItems(metadata.Indexes, container.Indexes); } return metadata; } static void MergeMetaItems(IList destinationCollection, IEnumerable source) { foreach(MetaItem item in source) { if(!ContainsMetaItem(destinationCollection, item)) { destinationCollection.Add(item); } } } static bool ContainsMetaItem(IList collection, MetaItem metaItem) { foreach(MetaItem item in collection) { if(item.Name.Equals(metaItem.Name)) { return true; } } return false; } }Please note that this code would create a new Database instance for each loaded module. You can avoid that if your application is able to determine when all modules have been loaded. In such a case the ObservableCollection<T> object can be substituted with a normal List<T>. I hope that helps.
Best wishes,
Alexander
the Telerik team