Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
How to build OData IEdmModel from Entity Framework model
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;
using System.Data.Entity.Infrastructure;
using System.Diagnostics;
using System.Xml;
using Microsoft.Data.Edm;
using Microsoft.Data.Edm.Csdl;
using Microsoft.Data.Edm.Validation;
namespace ODataServices
public abstract class ODataEntityFrameworkModelBuilder
private const string CsdlFileExtension = ".csdl";
private const string EntityConnectionMetadataPatternText = @"^(res://\*/(?<name>[^\|]+))(\|res://\*/(?<name>[^\|]+)?)*$";
private const RegexOptions EntityConnectionMetadataRegexOptions =
RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture;
private static readonly Regex EntityConnectionMetadataPattern =
new Regex( EntityConnectionMetadataPatternText, EntityConnectionMetadataRegexOptions );
private static Stream GetCsdlStreamFromMetadata( IObjectContextAdapter context )
var metadata = new EntityConnectionStringBuilder( context.ObjectContext.Connection.ConnectionString ).Metadata;
return ( from Match match in EntityConnectionMetadataPattern.Matches( metadata )
from Capture capture in match.Groups[ "name" ].Captures
where capture.Value.EndsWith( CsdlFileExtension )
let assembly = Assembly.GetAssembly( context.GetType() )
select assembly.GetManifestResourceStream( capture.Value ) ).Single();
[System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2202:Do not dispose objects multiple times" )]
public static IEdmModel GetEdmModel<T>() where T : DbContext, new()
using ( Stream csdlStream = GetCsdlStreamFromMetadata( new T() ) )
using ( XmlReader reader = XmlReader.Create( csdlStream ) )
IEdmModel model;
IEnumerable<EdmError> errors;
if ( !CsdlReader.TryParse( new[] { reader }, out model, out errors ) )
foreach ( var e in errors )
Debug.Fail( e.ErrorCode.ToString( "F" ), e.ErrorMessage );
return model;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Web.Http;
using System.Web.Http.OData.Routing;
namespace ODataServices {
public static class WebApiConfig {
public static void Register( HttpConfiguration config ) {
// Enables OData support by adding an OData route and enabling querying support for OData.
routeName: "ODataRoute",
routePrefix: "odata",
model: ODataEntityFrameworkModelBuilder.GetEdmModel<SomeDbContext>()
// To disable tracing in your application, please comment out or remove the following line of code

dariusclay commented Jan 28, 2014

Works with ODataLib 5.6.0, EdmLib 5.6.0 and EntityFramework 6.0.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment