问题
I'm trying to write an OData v3 Backend for use in an .NET4 application. I want to use BreezeJS on the client side. For the server/OData implementation I use ODataLib v1-3.
In order to generate metadata for an existing model I followed the guidelines here: http://www.getbreezenow.com/documentation/ef-design-tool
(more specifically the part "The metadata-only DbContext")
which describes how to use the Entity Framework as a design time tool to generate a IEdmModel and Metadata. I use the EdmBuilder from the BreezeJS Server Labs repository.
All dependencies are installed via Nuget:
- Breeze Labs EdmBuilder (1.05)
- ODataLib for OData v1-3 (5.63)
- EdmLib for OData v1-3 (5.63)
- EntityFramework (6.12)
The good news is: I can generate metadata and deliver it to the client.
The bad news is: DataJs which is responsible of parsing metadata when using BreezeJS with OData config is not accepting the metadata.
The problem is: Somebody sets the wrong EDMX version in the root xml element and it is not me. This is causing DataJs to drop the received metadata. The EDMX version for v3 should be 1.0 as defined in the OData v3 specs.
I'm out of ideas (other than replacing it "by hand") on what to do about this and if I ran into a dead end. Doing metadata by hand is not really an option since I need a maintainable solution.
Generated Metadata:
<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
<edmx:DataServices m:DataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<Schema Namespace="ODataMetaDataGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
[... schema content left out for brevity ...]
</Schema>
</edmx:DataServices>
</edmx:Edmx>
EDIT: Update on what I have found: The EdmBuilder from Breeze Server Labs is using the EdmxWriter which in turn uses the EdmxSerializer. There is some code which determines the namespace according to the SchemaVersion of the involved EdmModel.
System.Data.Entity.ModelConfiguration.Edm.Serialization.EdmxSerializer
public void Serialize(DbDatabaseMapping databaseMapping, XmlWriter xmlWriter)
{
this._xmlWriter = xmlWriter;
this._databaseMapping = databaseMapping;
this._version = databaseMapping.Model.SchemaVersion;
this._namespace = object.Equals((object) this._version, (object) 3.0) ? "http://schemas.microsoft.com/ado/2009/11/edmx" : (object.Equals((object) this._version, (object) 2.0) ? "http://schemas.microsoft.com/ado/2008/10/edmx" : "http://schemas.microsoft.com/ado/2007/06/edmx");
this._xmlWriter.WriteStartDocument();
using (this.Element("Edmx", "Version", string.Format((IFormatProvider) CultureInfo.InvariantCulture, "{0:F1}", new object[1]
{
(object) this._version
})))
{
this.WriteEdmxRuntime();
this.WriteEdmxDesigner();
}
this._xmlWriter.WriteEndDocument();
this._xmlWriter.Flush();
}
Can I influence the SchemaVersion in any way?
UPDATE:
I found a workaround which involves setting the EdmxVersion manually on the EdmModel generated by Breeze's EdmBuilder:
/// <summary>
/// Builds an Entity Data Model (EDM) from an
/// existing <see cref="DbContext" /> created using Code-First.
/// Use <see cref="GetModelFirstEdm" /> for a Model-First DbContext.
/// </summary>
/// <typeparam name="T">Type of the source <see cref="DbContext" /></typeparam>
/// <param name="dbContext">Concrete <see cref="DbContext" /> to use for EDM generation.</param>
/// <returns>An XML <see cref="IEdmModel" />.</returns>
private static IEdmModel GetCodeFirstEdm<T>(this T dbContext) where T : DbContext
{
using (var stream = new MemoryStream())
{
using (var writer = XmlWriter.Create(stream))
{
EdmxWriter.WriteEdmx(dbContext, writer);
}
stream.Position = 0;
using (var reader = XmlReader.Create(stream))
{
IEdmModel model = EdmxReader.Parse(reader);
// this line sets the edmx version manually
// can also happen outside of this implementation but maybe it is a general fix?
model.SetEdmxVersion(new Version(1, 0));
return model;
}
}
}
Still have to verify if this now is working. Will report back.
UPDATE:
Metadata seems to be working but now I have problems with Enums in my model which cause an Exception in Breeze client. Currently debugging that to gain more insight on whats happening.
Opened a new question for the new problem: Exception while parsing metadata in BreezeJS client
来源:https://stackoverflow.com/questions/28077699/how-to-generate-valid-metadata-from-ef-dbcontext-via-edmbuilder-for-odata-v3-bre