【问题标题】:WebApi OData query with complex type ignores nested values具有复杂类型的 WebApi OData 查询忽略嵌套值
【发布时间】:2016-11-15 21:06:47
【问题描述】:

我使用实体框架创建了一个 DbContext。 Dbcontext 在 WebApi 项目中创建。 DbContext 中的一张表代表建筑物。该位置在数据库中表示为地理类型。我需要查询建筑物并按到给定位置的距离对结果进行排序。

用于查询的类型是

[DataContract]
public class BuildingDistance
{
    [Key]
    [DataMember]
    public string Id { get; set; }
    [DataMember]
    public string Street { get; set; }
    [DataMember]
    public double? Distance { get; set; }
    [DataMember]
    public t_building Building { get; set; }
}

此类型已在模型构建器中注册

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
// ... Registration of the types generated by EF
builder.EntitySet<t_building>("t_building");
builder.EntitySet<BuildingDistance>("BuildingDistances");

我定义了以下控制器操作

        public IHttpActionResult GetBuildingDistances(ODataQueryOptions<BuildingDistance> queryOptions)
    {
        // validate the query.
        try
        {
            queryOptions.Validate(_validationSettings);
        }
        catch (ODataException ex)
        {
            return BadRequest(ex.Message);
        }

        dbcontext db = new dataBaseEntities();
        string pointString = string.Format(CultureInfo.InvariantCulture.NumberFormat, "POINT({0} {1})", 11.53128, 48.17883);
        DbGeography myLocation = DbGeography.FromText(pointString, 4326);
        var query =
            db.t_building.Select(
                x =>
                    new BuildingDistance
                    {
                        Id = x.id,
                        Street = x.location_street,
                        Building = x,
                        Distance = x.GeoLocation.Distance(myLocation)
                    });

        var result = queryOptions.ApplyTo(query) as IQueryable<BuildingDistance>;

        return Ok(result);
    }

执行查询并将结果发送给客户端。问题是属性 Building 不存在

{  "odata.metadata":"http://localhost:50732/odata/$metadata#BuildingDistances","value":[
{
  "Id":"15FF94FE-3CB8-4CF6-BE89-501A8366ED7C","Strasse":"Maistr.","Distance":4407.0418114105069
}  ]

}

实际上只填充了属性 ID、距离和街道。物业大楼被排除在外。

如果我在 LinqPad 中运行此查询,则会填充属性 Building。

属性不是只读的,因此排除了here 的情况。

感谢您的任何建议!

更新:尝试了范欧阳推荐的方法,我得到以下错误

“ObjectContent`1”类型未能序列化响应正文 内容类型'应用程序/json; charset=utf-8'。

更新:尝试使用 OData 的导航属性方法使用 Attribute ForeignKey。运气不好,有和没有 $expand。

【问题讨论】:

    标签: entity-framework asp.net-web-api odata


    【解决方案1】:

    你应该有

    $expand=Building 
    

    在有效载荷中具有导航属性的查询中。

    当查询中有$expand或$select时,applyto方法的结果类型将是WebAPI/OData中的包装类,所以你应该去掉as IQueryable&lt;BuildingDistance&gt;,使用https://github.com/OData/WebApi/blob/master/OData/test/E2ETest/WebStack.QA.Test.OData/DollarLevels/DollarLevelsController.cs#L62-L63这样的代码

    或者您可以在控制器方法中使用 EnableQuery 属性并返回查询:

    [EnableQuery]
    public IHttpActionResult GetBuildingDistances()
    {
        ...
        var query =
            db.t_building.Select(
                x =>
                    new BuildingDistance
                    {
                        Id = x.id,
                        Street = x.location_street,
                        Building = x,
                        Distance = x.GeoLocation.Distance(myLocation)
                    });
        return Ok(query as IQueryable<BuildingDistance);
    }
    

    【讨论】:

    • 感谢您的评论!建议不起作用,我在更新到 OP 时发布了错误消息。
    • 现在我可以使用扩展和选择了。我选择了第二种解决方案([EnableQuery] with a cast)。谢谢范欧阳!
    猜你喜欢
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    • 2013-12-03
    • 1970-01-01
    • 2019-01-05
    • 1970-01-01
    • 1970-01-01
    • 2022-12-15
    相关资源
    最近更新 更多