The title says it all really. I've found several blogs with different ways (serializing the EF model to XML and then de-serializing again to the IEdmModel was one) but they're all based on old version of the OData package.
2 Answers
Serializing is the only way.
I've ranted about this a few months ago. AFAIK nothing changed since then, and I personally don't expect them to change too much. The short story is that as of September 2012, there is no plan to use EdmLib in EF, nor is there to use EF's code in other projects.
How much should we align with OData’s EdmLib?
Not worth adopting code Cost of implementing SSDL & MSL Freedom to evolve our API independently Look at aligning names of types and properties where appropriate

- 7,071
- 2
- 45
- 68
-
1That example doesn't seem to work. I can see from the `return` statement that it uses `Microsoft.Data.Edm.Csdl.EdmxReader.Parse`, which will obviously produce `Microsoft.Data.Edm.IEdmModel`, whereas we want the `IEdmModel` in the `OData` namespace. – Asad Saeeduddin Jun 15 '15 at 16:19
-
@Asad Things have [changed](http://stackoverflow.com/q/28019669) indeed. I couldn't find the documentation for the new `.OData` namespace on MSDN, though I think [here](https://odata.github.io/) is the new official place for the implementation project. There doesn't appear to be a reference documentation set right now but there is a "tutorial". The relevant section is [this one](https://odata.github.io/odata.net/#02-02-read-write-model). The API looks similar. – tne Jun 15 '15 at 19:50
-
I've since found the relevant new API for parsing edmx files, but it chokes on the edmx you serialize from a `DbContext`. I gave up and downgraded to OData v3. – Asad Saeeduddin Jun 15 '15 at 20:02
-
@Asad That's too bad. Theoretically the CSDL schemas should be compatible, so if you have the time I think either team (whoever got it wrong) would appreciate a bug report. – tne Jun 15 '15 at 20:17
-
@tne The problem is that both the embedded CSDL and the CSDL `Microsoft.Data.Edm.Csdl.CsdlWriter` writes are OData v3. But `Microsoft.OData.Edm.Csdl.CsdlReader` only accepts OData v4. I haven't been able to find a way to bridge those two. The same goes for the EDMX. I have a really large DB model I want to make accessible via OData v4. I have created the model with the EF wizard and can access it with a WCF Data Service and OData v3. Do you have any ideas what else I could try to make it work with OData v4? – ctusch Sep 25 '15 at 23:42
-
@user232986 Sorry I'm a little out of touch. The scenario sounds very typical (almost archetypal) so I'd tend to believe you *do* have options. Have you tried [RESTier](https://odata.github.io/RESTier/)? It does take an EF model to expose an OData v4 endpoint per your requirements. Otherwise we used to get by without CSDL interop before the serializers appeared by regenerating OData models from CIL code ("convention model builder") which you'd get by building either code-first EF models or code generated by the EF T3 templates applied to an EDMX (fun times). Don't know if that still works. – tne Sep 26 '15 at 00:06
-
@tne Thanks for the hint! I also thought that would be the standard use case. I've tried RESTier now and got it working. The problem is that it supports only part of OData (e.g. no $count). But then I dug into its code to see how it generates its $metadata. Turns out it's building an `Microsoft.OData.Edm.IEdmModel` internally. So I called that API directly and passed it to WebAPI's (?) `MapODataServiceRoute` method. $metadata worked but when I tried opening an entity set I got `No type was found that matches the controller named
`. Maybe WebAPI can't be used like that. – ctusch Sep 28 '15 at 22:15 -
@user232986 I think `MapODataServiceRoute` routes requests to per-entity controllers, while `MapODataDomainRoute` (from RESTier) routes requests to "per-domain" (multiple entities) controllers (of type `ODataDomainController`). So I wouldn't think it'd work; you must use one or the other. If you're fine with per-entity controllers then you don't need RESTier AFAICT. – tne Sep 29 '15 at 08:38
-
@tne That would explain a lot. :) Per-entity controllers are no option since I would have to create them manually (if I understand this correctly) and I have more than 500 entities. Well I guess I will have to stick with OData v3. We are using ASP.NET only as an intermediate solution anyway and this starts to eat too much time. Thanks a lot again for your help! – ctusch Sep 29 '15 at 13:26
-
@user232986: Note that they present a workaround for the lack of `$count` support in RESTier (see [main page](https://odata.github.io/RESTier/)), though because of your reqs you'd have to generate that code somehow (e.g. T4 templates). You should probably send them a report stating your interest for the feature regardless. I hear you though, the MSFT OData story was a big matter of bad timing for us (WCF-DS dropped at a bad time, RESTier didn't exist, and it's evidently not fully ready yet -- we had to stop our OData-related work). – tne Sep 29 '15 at 13:49
-
@tne Yeah I saw that but as you said I would have to generate code for each entity again. Also they state they only have very basic OData support so who knows what else is missing. It's a real pity that OData is generally supported so badly (even by Microsoft). – ctusch Sep 30 '15 at 08:39
If your DbContext is being built from a database-first approach the given answer will fail giving this error:
Creating a DbModelBuilder or writing the EDMX from a DbContext created using Database First or Model First is not supported. EDMX can only be obtained from a Code First DbContext created without using an existing DbCompiledModel.
After some time messing with this I have found an appropriate solution. Basically you grab the CSDL resource from the assembly containing the DbContext in question and parse it using the Microsoft.Data.Edm.Csdl.CsdlReader.TryParse method. The resulting IEdmModel is valid containing the exact information given by EntityFramework when the model was built.
See here for an example with usage

- 1,069
- 9
- 19