Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ddpruitt/ac94418c22b76082e3adfbeeb91236c1 to your computer and use it in GitHub Desktop.
Save ddpruitt/ac94418c22b76082e3adfbeeb91236c1 to your computer and use it in GitHub Desktop.
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.
config.Routes.MapODataRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: ODataEntityFrameworkModelBuilder.GetEdmModel<SomeDbContext>()
);
config.EnableQuerySupport();
// To disable tracing in your application, please comment out or remove the following line of code
config.EnableSystemDiagnosticsTracing();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment