Last active
December 1, 2022 22:35
-
-
Save dariusclay/8673940 to your computer and use it in GitHub Desktop.
How to build OData IEdmModel from Entity Framework model
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
Very interesting, did you try the same with latest versions and .net Core?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Works with ODataLib 5.6.0, EdmLib 5.6.0 and EntityFramework 6.0.2