I’ve posted in the Entity Framework forum about this but I wanted to document it here as well because when I was researching this problem I found very little information. Here’s the deal:
I have a single project with multiple models. Some of the models have entities that are mapped back to the same tables in the store. (i.e. two models have a Customer entity that is mapped back to the Customer table.) I am using the Self-Tracking entity templates and each template is in it's own folder with its own namespace and the template code points to the actual edmx file that is in another project. Those templates are all in a separate assembly from the project that contains the models and the context templates. The project with the models and contexts has a reference to the assembly containing the generated self-tracking entities. Everything generates and compiles fine.
At runtime I get the following error when I try to use one of the generated contexts:
Schema specified is not valid. Errors:
The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type 'Customer'. Previously found CLR type 'MyProject.Common.Contracts.Data.OrderManagementModel.Customer', newly found CLR type 'MyProject.Common.Contracts.Data.CustomerManagementModel.Customer.
Lingzhi Sun, one of the Microsoft moderators, asked for some clarification so I elaborated for him:
I have discovered that this is a known issue since the beginning of EF. I'm sorry I don't have a link for you. I'm not sure if this has been filed as a bug in connect or anywhere. Daniel Simmons of the EF team can likely confirm this for you. I'll elaborate more here as in my search I found little out there that describes this exact problem.
You are correct that the STE classes are in a separate assembly and each tt file is in its own directory so that the generated classes are in a separate namespace from the classes generated for other models. The same is true for the models in a separate assembly. For example:
Shared contract library structure:
The server-side data assembly has a reference to the shared contract assembly. I've modified the STE tt code to fix up the reference to the edmx file. I've also modified the server-side tt files that generate the ObjectContext to include an additional using statement so that they know about the STEs in the shared assembly. As I mentioned, at compile time, everything is happy.
The problem, as I understand it, is that at runtime when CreateObjectSet<SomeSteType>("SomeSteType") gets called only the type name is used to find the CLR type. Namespaces are completely ignored. Even if you changed the code-gen to produce:
The namespace is still ignored. The upshot of this is that if you have two classes within the same assemble that have the same name, you will get the error in my above. The irony of the whole thing is that the error message tells you the FQN of the types it found but can't distinguish between them. Perhaps there is some technical reason why the namespace is ignored when resolving the types but I can't think of one. It seems obvious that to be certain you get the right type, you need to use the FQN.
The easiest and most obvious work-around is to simply make sure that every type in the same assembly has a unique name. Since something like Customer would be common in both the CustomerModel and the OrderModel you can just rename one of them to be Customer1. At least in Intellisense then you still type Customer and in context you would only see one or the other so it's not too terrible. It's just messy.
The other work-around is to separate them into different assemblies. This is also less than optimal as I have 10 different models and I'm not even done yet. (there are hundreds of tables in the database)
So there in a nutshell is the problem. I'd be interested to know if (a) this is an actual bug being tracked by the EF team, (b) is it on the roadmap for a future update and (c) what time frame for a fix can we expect?
Just because I can…