我在OData V4
(Asp.net WebApi
)上有OWIN
。
除我尝试查询4级$expand
之外,其他所有方法都很好。
我的查询如下:
http://domain/entity1($expand=entity2($expand=entity3($expand=entity4)))
我没有收到任何错误,但是我的回复中没有计划最后的扩展。
更多信息:
MaxExpandDepth
设置为10。EntitySets
。ODataConventionModelBuilder
。$expands
,但它们也无法正常工作。编辑:
我已覆盖OnActionExecuted
:
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
var objectContent = actionExecutedContext.Response.Content as ObjectContent;
var val = objectContent.Value;
var t = Type.GetType("System.Web.OData.Query.Expressions.SelectExpandWrapperConverter, System.Web.OData");
var jc = Activator.CreateInstance(t) as JsonConverter;
var jss = new JsonSerializerSettings();
jss.Converters.Add(jc);
var ser = JsonConvert.SerializeObject(val, jss);
}
序列化的值包含实体4。
我仍然不知道哪个组件会删除管道中的entity4。
编辑#2:
我已经在DefaultODataSerializerProvider
和所有其他ODataEdmTypeSerializer's
上创建了一个适配器。我看到在此过程中,entity4的$expand
存在,并且在该navigationProperty(entity4)上调用了ODataResourceSerializer.CreateNavigationLink
方法时,它返回了null。
我跳到源代码中,可以看到SerializerContext.Items
的项目中未包含实体4,而SerializerContext.NavigationSource
为空。
要具体说明版本,我使用的是System.Web.OData, Version=6.1.0.10907
。
答案 0 :(得分:3)
好吧,所以我注意到问题是由于我的导航属性为EdmUnknownEntitySet
类型,并且导航属性查找返回null(源代码带有错误的TODO。):
/// <summary>
/// Finds the entity set that a navigation property targets.
/// </summary>
/// <param name="property">The navigation property.</param>
/// <returns>The entity set that the navigation propertion targets, or null if no such entity set exists.</returns>
/// TODO: change null logic to using UnknownEntitySet
public override IEdmNavigationSource FindNavigationTarget(IEdmNavigationProperty property)
{
return null;
}
所以我知道我的问题出在EdmUnknownEntitySet
上。
我深入研究代码,发现需要将ContainedAttribute
添加到导航属性中。
由于我的解决方案属于通用存储库,因此已将其添加到“所有导航的启动”属性中:
builder.OnModelCreating = mb => mb.StructuralTypes.SelectMany(s => s.NavigationProperties
.Where(np => np.Multiplicity == EdmMultiplicity.Many)).Distinct().ForEach(np => np.Contained());
//......
var model = builder.GetEdmModel();