使用Entity Framework我创建了一个DbContext。 Dbcontext是在WebApi项目中创建的。 DbContext中的一个表代表建筑物。该位置在数据库中表示为Geography类型。我需要查询建筑物并按照到给定位置的距离对结果进行排序。
用于查询的类型是
[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; }
}
此类型已在modelbuilder中注册
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);
}
执行查询并将结果发送到客户端。问题是缺少建筑属性
{ "odata.metadata":"http://localhost:50732/odata/$metadata#BuildingDistances","value":[
{
"Id":"15FF94FE-3CB8-4CF6-BE89-501A8366ED7C","Strasse":"Maistr.","Distance":4407.0418114105069
} ]
}
实际上只填充了属性ID,距离和街道。酒店大楼被遗漏了。
如果我在LinqPad中运行此查询,则会填充属性Building。
属性不是只读的,因此排除here的情况。
感谢您的任何建议!
更新:尝试了范欧阳推荐的方法,我收到以下错误
&#39; ObjectContent`1&#39;类型无法序列化响应正文 内容类型&#39; application / json;字符集= UTF-8&#39;
更新:尝试使用属性ForeignKey使用OData的导航属性方法。没有运气,有无扩张。
答案 0 :(得分:0)
你应该
$expand=Building
在查询中,在有效负载中包含导航属性。
当查询中有$ expand或$ select时,applyto方法的结果类型将是WebAPI / OData中的包装类,因此您应该删除as IQueryable<BuildingDistance>
并使用{{3}之类的代码}
或者您可以在控制器方法中使用EnableQuery Attribute并返回查询:
[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);
}