views:

505

answers:

1

I am currently transitioning an application over from LINQ-to-SQL and I've been running into a problem.

LINQ-to-SQL offered a way to query any Table/Column-attributed type (which was the default mapping model) through any DataContext through the GetTable<T> function, which analyzed the type and then created the appropriate SQL. Even though there were strongly typed DataContexts, for the most part, they weren't needed if you were just doing CRUD operations against basic table types.

This was great, because in classes outside of my assembly, I could define a pre-existing query in the form of IQueryable<T1> as well as a DataContext, and then allow them to return IQueryable<T2>, possibly using their own types which would have representations in the same underlying database that the DataContext was connected to.

Because of this, I could have all of my data objects compiled in one assembly, make the call to the external assembly, let them transform the query, and execute it for the results.

In moving to EF, I've found that is no longer the case. There is something comprable in the CreateQuery<T> method on ObjectContext, but that means that the ObjectContext has to have a MetadataWorkspace which is pre-loaded with all of the appropriate mapping files.

That works fine if all the mappings are stored in one assembly. If not, then you have to tell the designer to copy the csdl, msl, and ssdl to an output directory and then load them manually through a combination of calls to RegisterItemCollection and LoadAssembly on the MetadataWorkspace.

Or, you can actually keep the csdl, msl and ssdl files as resources in the various assemblies and simply call the constructor on MetadataWorkspace which will take a number of paths and Assembly types and pass "res://*/" for the path, and multiple assemblies.

Either way is fine for me.

The question that I have is the where the mapping views that are created by EF are stored.

I have read this on MSDN that indicates that you can increase performance by pre-generating the mapping views for entities:

http://msdn.microsoft.com/en-us/library/bb896240.aspx

And indeed, it does improve performance.

The question I have is that if I am generating one MetadataWorkspace and then sharing it among EntityConnections (which I then pass to ObjectContexts and perform my work on), is the mapping view stored in the MetadataWorkspace, the EntityConnection, or ObjectContext?

I've set breakpoints in the pre-compiled view code, and it would seem that it is only called once, no matter how many EntityConnections or ObjectContexts I create, as long as I use a shared MetadataWorkspace, which would suggest to me that the view mappings are indeed stored there.

So for a sanity check, is this correct?

Also, as a follow-up, is it worth it? If I am creating a shared MetadataWorkspace and then passing it to all EntityConnections and ObjectContext instances and NOT pre-compiling mapping views, then there is at the least a one-time performance hit that is incurred in generating the mapping view.

The question here is that if I am using the shared MetadataWorkspace, and the mapping view is indeed generated and stored on that level, then does that mean that as long as I use the shared MetadataWorkspace across all EntityConnection/ObjectContext instances, I will incur the map generation cost just once?

If that is the case, then it doesn't make sense (for the purposes of my application, not in general) to pre-generate the views.

That is assuming of course, that it is stored on the MetadataWorkspace level and that even without pregenerated mapping views, the cost is one time for the instance of the MetadataWorkspace.

Can someone validate this or not for me?

Thanks in advance.

A: 

Damn, I would really like to know the answer to your question, I'm currently going through the same reflexion. (I have a very large EDMX file, and generating all the views seems pointless with comparison to sharing a metadataworkspace which could cache the views... hopefully)

Sylvain