This is a migrated thread and some comments may be shown as answers.

Type is enhanced and registered, but not available from the database class meta data

11 Answers 338 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
DusterMynes
Top achievements
Rank 1
DusterMynes asked on 08 Apr 2011, 04:21 PM
1 -First, I had no problems using one orm schema in my solutions metadatasource (.rlinq) for retrieving objects from my oracle database.

2 - My problems start when I tried to use a second orm schema in another dll referenced by the first project.

ProjectBusiness.prj            ----------------> ProjectBase.prj
     --ProjectBusiness.rlink                                --ProjectBase.rlink

3-The problem occurs when I request an object from ProjectBase.rlink and throw this exception : "Type is enhanced and registered, but not available from the database class meta data"

I realize that the OpenAccessContext of ProjectBaseDiagrams:OpenAccessContext use the metadatasource of ProjectBusinessDiagrams.

Finally I found in you class : Telerik.OpenAccess.OpenAccessContextBase
that your property "Metadata" is described as follows (at the bottom).  Maybe there's a problem with you Database.Get static Method returning the first database loaded(ProjectBusinessDiagrams) if we use the same connectionstring?

Is it possible to use 2 or more entitydiagrams in same application?

-------------------------------------------------------------------------------------------

public MetadataContainer Metadata
{
    get
    {
        MetadataContainer metaData;
        this.CheckDispose();
        bool onlyMetadata = this.backendConfiguration.Runtime.OnlyMetadata;
        Database database = null;
        try
        {
            if (this.database == null)
            {
                this.backendConfiguration.Runtime.OnlyMetadata = true;
                database = Database.Get(this.connectionString, this.backendConfiguration, this.metadataContainer);
                return database.MetaData;
            }
            this.GetScope();
            metaData = this.database.MetaData;
        }
        finally
        {
            this.backendConfiguration.Runtime.OnlyMetadata = onlyMetadata;
            if ((database != null) && !database.IsCached())
            {
                database.Dispose();
            }
        }
        return metaData;
    }
}

            

11 Answers, 1 is accepted

Sort by
0
Serge
Telerik team
answered on 13 Apr 2011, 03:56 PM
Hi Dom,

 First of all we have to make sure that both of your model, as I understand in different projects and mapped by different rlinq files, are enhanced. Please open both project containing rlinq files and check if the following line exists in them (you have to open with a text editor the csproj/vbproj files) : 

<Import Condition="Exists('$(MSBuildExtensionsPath)\OpenAccess.targets')" Project="$(MSBuildExtensionsPath)\OpenAccess.targets" />

If it is not available, please add it somewhere near the end of the file. In these targets there is one running the enhancer after each compilation, which is a necessary step for OpenAccess to work. 

If that is not the problem the problem might be if both context instances are using the same connection string. You see internally a context instance works with a static Database object that holds the mapping information needed. The problem is that for each connection string name only one Database object is stored. And if two different context instances are using the same connection string they both will use the Database object that is created first. Which means that one of your models mapping information will not be available and this exception might occur. 

In order to work around this issue you can either make sure that the database object created with this connection string name holds the information for both model (which would mean manually instantiating one) or make sure that both context classes use different connection strings (they can be the same however the names of the connection strings have to be different).

I hope this proves to be helpful, please do let us know if you want to merge the mapping information and create the database instance by yourself so that we can provide information on how to do that exactly. 

Best wishes,
Serge
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
DusterMynes
Top achievements
Rank 1
answered on 14 Apr 2011, 04:36 PM
Thanks for your response,

As you mentionned, my problem is due to this:

"The problem is that for each connection string name only one Database object is stored. And if two different context instances are using the same connection string they both will use the Database object that is created first. Which means that one of your models mapping information will not be available and this exception might occur. "

Its seem to be a design flaw because the constructor of class OpenAcessContext have a MetadataSource as a parameter.

public OpenAccessContext(string connectionString, BackendConfiguration backendConfiguration, MetadataSource metadataSource);

Is it something that you'll fix, probably an easy task?

Nevertheless, the workaround of creating a new user for the same Database is working.
0
Serge
Telerik team
answered on 15 Apr 2011, 12:37 PM
Hello Dom,

 Unfortunately at the moment we have no plans for changing this behaviour. And this is because the disposal and creation of a Database object is not a lightweight operation. 

However I am glad that you have managed to get your application running. 

All the best,
Serge
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Rutger Buijzen
Top achievements
Rank 2
answered on 29 Mar 2012, 10:48 AM
I need to develop multiple DNN modules within the same DNN instance, each with their own data model ...

this means I now have to add separate connections strings for each module???

there should be a better way.... ???
0
Serge
Telerik team
answered on 29 Mar 2012, 05:48 PM
Hello Rutger,

 Unfortunately for the time being there is no better way. One thing you could do however is accumulate all of the metadata in a single database instance. Each time you activate a module, just dispose of database object and append the new metadata to the one already available. This comes with the issue though that while doing this operation all other request will have trouble.

I can provide you with some sample code if this is something that you will find useful.
 
All the best,
Serge
the Telerik team
Telerik OpenAccess ORM Q1 2012 release is here! Check out what's new or download a free trial >>
0
Rutger Buijzen
Top achievements
Rank 2
answered on 30 Mar 2012, 11:01 AM
hmmm... doesn't sound like a real solution (since it will cause other issues...)

like I said I have independend modules that have indepent tables.
so I need to have separate model for each module.
all data already is in the same database

for example: Tables:
  • ModuleATable
  • ModuleBTable

Some clients will install only ModuleA, some only ModuleB and some will install both modules.

Could you add feature request to make it possible to use single connection string?

(I guess you use connectionstring as a key somehow?)


0
Serge
Telerik team
answered on 04 Apr 2012, 11:29 AM
Hello Rutger,

 I have added a new item in out Public Issue Tracking system, that you can vote for. You can find it here

And yes, it is exactly the connection string that we use as a key for the Database Register.

Greetings,
Serge
the Telerik team
Telerik OpenAccess ORM Q1 2012 release is here! Check out what's new or download a free trial >>
0
Mike
Top achievements
Rank 1
answered on 07 Sep 2013, 05:24 AM
Hey all. 

Ran into this myself and came up with a pretty quick workaround!

The "key" to the solution was in Serge's last response:
Serge said: "And yes, it is exactly the connection string that we use as a key for the Database Register."

So... if the connection string itself is the "key" in this magical Database Register then theoretically all we would have to do is modify the connection string slightly and it would be a new entry in that Database Register.

And a quick test proved this to be the case!

For that quick test I just had the method responsible for serving up connectionstrings add a random guid to a normally unused connection string paramater:
Data Source=server;Initial Catalog=myDb;Integrated Security=False;User ID=myUser;Password=pass;MultipleActiveResultSets=True;Application Name=be0cb86d-bf57-420e-b941-a581ec2d036b

(In case you didn't catch it "Application Name" was the normally unused parameter...don't think I've ever used that in my entire life.)

With this in place the error went away as expected - Yay!


Now, as a proof of concept this works great..but it's probably in our best interest to be mindful of that internal Database Register else it would likely get bloated pretty quickly.

So, rather than a random guid instead I'd recommend simply passing in your modelName (or even module name in Rutger's case), etc. and set that "Application Name" parameter to it. Now you will have a single Database Register entry for each of your models and everything works as expected. ;)


Hope this helps!

PS:
For the record I was doing this with multiple models all in the same Project so if it can work that way it will definitely work with them split in multiple projects as well.

Also, just want to add: Just made the switch from EF today and I'd gladly take a few little issues like this over some of the complete weirdness I've experienced with EF. So far very pleased. :)

Thanks
Mike


0
Kaloyan Nikolov
Telerik team
answered on 11 Sep 2013, 01:59 PM
Hello Mike,

we confirm that your approach is absolutely valid and it should not cause any issues. As you noted the only thing that you should be careful about is that the unique part of the connection string should remain one and same per context type during the application lifetime. If you create unique connection string for every context instance this could lead to performance and memory issues. 

As it is crucial for some of our customers to be able to control the internal Database caching we are working on a feature which will expose the cache key. You will be able to specify it directly instead of playing with the connection string. Furthermore for the cases with multiple models against same database you should not face the described issue any more, it will work out of the box.
Your approach will not be deprecated. 

The new feature will be released soon, so stay tuned.

Regards,
Kaloyan Nikolov
Telerik
OpenAccess ORM Q2 2013 brings you a more powerful code generation and a unique Bulk Operations support with LINQ syntax. Check out the list of new functionality and improvements shipped with this release.
0
test
Top achievements
Rank 1
answered on 09 Apr 2014, 09:14 AM
Hi,

We've got the same problem : we have several DNN modules, each one have its own model pointing all on the same connectionstring (DNN's connectionstring SiteSsqlServer). But... unfortunatly the solution found by Magic is not working for us, if we add the parameter "Application Name" in the value of AppConfigConnectionString key (with a different value for "Application Name" for each module), we've got always the same problem.

The only solution we found is to change the AppConfigConnectionPropertyName value. We don't change the name of the connectionstring (it's always SiteSqlServer) but we write it with different case (exemple : SiteSqlServer, SIteSqlServer, SITeSqlServer...), then it works... but it's really a horrible solution !!

We use 2013.1.69.2369 version of Telerik.OpenAccess.

In its last post Kaloyan said the featured describe by Mike wouldn't be depreciated, are you sure ?

Any news about cache key feature ?
0
Kaloyan Nikolov
Telerik team
answered on 10 Apr 2014, 11:28 AM
Hi,

The new feature mentioned below is called "Multiple Models" and it is released with Telerik Data Access Q3.2013. It should make it easier to work with multiple models targeting one and the same data base. If you don't have multiple classes mapped to one and the same table across your models it should work without any changes in your code. If you have such case you should override the CackeKey property for each of your contexts and provide a different value in order to separate their metadata completely. 

The workaround (to provide insignificant changes in the connection string or in its name) will not be deprecated as it is used from some of our clients. We have tests in our test suite that validate it still works that way. However I would suggest you to upgrade to the latest version and use the new feature instead. 

I hope this helps. Should you have any further questions do not hesitate to get back to us.

Regards,
Kaloyan Nikolov
Telerik
 
OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
 
Tags
General Discussions
Asked by
DusterMynes
Top achievements
Rank 1
Answers by
Serge
Telerik team
DusterMynes
Top achievements
Rank 1
Rutger Buijzen
Top achievements
Rank 2
Mike
Top achievements
Rank 1
Kaloyan Nikolov
Telerik team
test
Top achievements
Rank 1
Share this question
or