我正在尝试编写一个用于.NET4应用程序的OData v3后端。我想在客户端使用BreezeJS。对于服务器/ OData实现,我使用ODataLib v1-3。
为了生成现有模型的元数据,我遵循了以下指南:http://www.getbreezenow.com/documentation/ef-design-tool
(更具体地说,“仅元数据的DbContext”部分)
描述了如何使用Entity Framework作为设计时工具来生成IEdmModel和元数据。我使用BreezeJS Server Labs存储库中的EdmBuilder。
所有依赖项都是通过Nuget安装的:
好消息是:我可以生成元数据并将其发送给客户。
坏消息是:在使用带有OData配置的BreezeJS时负责解析元数据的DataJs不接受元数据。
问题是:有人在root xml元素中设置了错误的EDMX版本,而不是我。这导致DataJs丢弃接收的元数据。 v3的EDMX版本应为OData v3 specs中定义的1.0。
我没有想法(除了“手动”替换它)关于如何做到这一点,如果我遇到了死胡同。手动执行元数据并不是一个选择,因为我需要一个可维护的解决方案。
生成的元数据:
<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>
修改 更新我发现的内容: Breeze Server Labs的EdmBuilder正在使用EdmxWriter,后者又使用EdmxSerializer。根据所涉及的EdmModel的SchemaVersion,有一些代码可以确定命名空间。
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();
}
我可以以任何方式影响SchemaVersion吗?
更新
我找到了一个解决方法,涉及在Breeze的EdmBuilder生成的EdmModel上手动设置EdmxVersion:
/// <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;
}
}
}
仍需要验证现在是否正常。将报告回来。
更新
元数据似乎正在运行,但现在我的模型中的Enums存在问题,导致Breeze客户端出现异常。目前正在调试,以便更好地了解发生的事情。
为新问题打开了一个新问题: Exception while parsing metadata in BreezeJS client