正如我在问题中提到的,我尝试了许多解决方案来使其正常工作,但在实际解决问题方面没有一个是一致的,我一直避免使用 this SO question/answer 中列出的解决方案,因为本教程专门针对 v4 和我认为答案必须针对旧版本(多么不明智)。
所以这个答案确实解决了问题,但需要一些工作才能直接适应 OData v4 和 ODataConventionModelBuilder;这就是我发布这个问题和答案的原因;提供一个解决方案,专门针对 OData v4 和 ODataConventionModelBuilder,希望其他人不会浪费我研究这个的时间。
首先,设置您的 EdmModel:
private static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.EnableLowerCamelCase();
builder.EntitySet<Menu>("Menus");
builder.EntitySet<MenuPermission>("MenuPermissions");
var edmModel = builder.GetEdmModel();
AddNavigations(edmModel); //see below for this method
return edmModel;
}
第二次添加导航:
private static void AddNavigations(IEdmModel edmModel)
{
AddMenuPermissionsNavigation(edmModel);
}
private static void AddMenuPermissionsNavigation(IEdmModel edmModel)
{
var menus = (EdmEntitySet) edmModel.EntityContainer.FindEntitySet("Menus");
var menuPermissions = (EdmEntitySet)edmModel.EntityContainer.FindEntitySet("MenuPermissions");
var menuType = (EdmEntityType) edmModel.FindDeclaredType("iiid8.cms.data.models.Menu"); //"iiid8.cms.data.models" is the C# namespace
var menuPermissionType = (EdmEntityType)edmModel.FindDeclaredType("iiid8.cms.data.models.MenuPermission"); //as above, "iiid8.cms.data.models" is the C# namespace
AddOneToManyNavigation("MenuPermissions", menus, menuPermissions, menuType, menuPermissionType);
AddManyToOneNavigation("Menu", menus, menuPermissions, menuType, menuPermissionType);
}
private static void AddOneToManyNavigation(string navTargetName, EdmEntitySet oneEntitySet, EdmEntitySet manyEntitySet,
EdmEntityType oneEntityType, EdmEntityType manyEntityType)
{
var navPropertyInfo = new EdmNavigationPropertyInfo
{
TargetMultiplicity = EdmMultiplicity.Many,
Target = manyEntityType,
ContainsTarget = false,
OnDelete = EdmOnDeleteAction.None,
Name = navTargetName
};
oneEntitySet.AddNavigationTarget(oneEntityType.AddUnidirectionalNavigation(navPropertyInfo), manyEntitySet);
}
private static void AddManyToOneNavigation(string navTargetName, EdmEntitySet oneEntitySet, EdmEntitySet manyEntitySet,
EdmEntityType oneEntityType, EdmEntityType manyEntityType) {
var navPropertyInfo = new EdmNavigationPropertyInfo {
TargetMultiplicity = EdmMultiplicity.One,
Target = oneEntityType,
ContainsTarget = false,
OnDelete = EdmOnDeleteAction.None,
Name = navTargetName
};
manyEntitySet.AddNavigationTarget(manyEntityType.AddUnidirectionalNavigation(navPropertyInfo), oneEntitySet);
}
最后,从 WebApiConfig.Register 调用 GetEdmModel
config.MapODataServiceRoute("odata", null, GetEdmModel());
现在从您的客户端调用您的 OData 服务的一对多和多对一导航,一切都应该适合您的世界。就我而言,调用如下所示:
一对多:
http://localhost:19215/Menus(c94f7f98-6987-e411-8119-984be10349a2)/MenuPermissions
多对一:
http://localhost:19215/MenuPermissions(ba0da52a-6c87-e411-8119-984be10349a2)/Menu
此答案假定您设置了项目的其余部分,就像 Mike Wasson 在问题中链接的教程中建议的那样(该链接指向第 3 部分 - 您首先需要 follow Part 1!)。