ASP.NET C# OData 服务 + 导航属性 + $expand = null。我错过了啥?
Posted
技术标签:
【中文标题】ASP.NET C# OData 服务 + 导航属性 + $expand = null。我错过了啥?【英文标题】:ASP.NET C# OData Service + Navigation Property + $expand = null. What am I missing?ASP.NET C# OData 服务 + 导航属性 + $expand = null。我错过了什么? 【发布时间】:2021-05-28 22:13:10 【问题描述】:我将尝试通过一个简化的示例尽可能彻底地解释我的问题。请注意,我没有使用实体框架。
我有这个模型:
public class Person
[Key]
public Guid Id get; set;
public string GivenName get; set;
public string FamilyName get; set;
public List<Employment> Employments get; set;
public class Employment
public string Role get; set;
public Guid? ManagerId get; set;
public virtual Person Manager get; set;
我创建了一个内存数据源:
public class MyDataSource
private static MyDataSource instance = null;
public static MyDataSource Instance
get
if (instance == null)
instance = new MyDataSource();
return instance;
public List<Person> Persons get; set;
private MyDataSource()
this.Persons = new List<Person>();
this.Persons.AddRange(new List<Person>
new Person()
Id = Guid.Parse("00000000-0000-0000-0000-000000000001"), //Just for simplicity
GivenName = "John",
FamilyName = "Doe",
Employments = new List<Employment>()
new Employment()
Role = "Boss"
,
new Person()
Id = Guid.Parse("00000000-0000-0000-0000-000000000002"), //Just for simplicity
GivenName = "Clark",
FamilyName = "Kent",
Employments = new List<Employment>()
new Employment()
Role = "Worker",
ManagerId = Guid.Parse("00000000-0000-0000-0000-000000000001"), //Just for simplicity
);
我有这个控制器:
[EnableQuery]
public class PersonsController : ODataController
public IHttpActionResult Get()
return Ok(MyDataSource.Instance.Persons)
我配置了 EndPoint:
public static class WebApiConfig
public static void Register(HttpConfiguration config)
config.MapODataServiceRoute("ODataRoute", "odata", CreateEdmModel());
config.Select().Expand().Filter().OrderBy().MaxTop(null).Count()
public static IEdmModel CreateEdmModel()
var builder = new ODataConventionModelBuilder();
var persons = builder.EntitySet<Person>("Persons");
builder.ComplexType<Employment>().HasOptional(e => e.Manager, (e, p) => e.ManagerId == p.Id);
return builder.GetEdmModel();
检查 $metadata 我看到了这个:
<NavigationProperty Name="Manager" Type = "MyNamespace.Person">
<ReferentialConstraint Property="ManagerId" ReferenceProperty="Id" />
</NavigationProperty
据我所知,一切看起来都很好,但是:
https://example.com/odata/persons?$expand=Employments/Manager
一切正常,但是:
Manager 对于两个人都是空的。我期待看到 John Doe 对 Clark Kents 的工作。
我错过了什么?
【问题讨论】:
【参考方案1】:我自己解决了。
我意识到它不像我想象的那样工作,我必须直接在 MyDataSource 中添加对管理器的引用。之后,它可以 $expand 管理器。
【讨论】:
如果您使用像 EntityFramework 这样的 ORM 作为数据源,那么只要 DbContext 可以解析查询,您最初的期望就会奏效。您已经有效地定义了手动投影,IQueryable 只能查询您定义的内容,因此您是正确的,您必须确保定义并包含对Manager
导航属性的引用。以上是关于ASP.NET C# OData 服务 + 导航属性 + $expand = null。我错过了啥?的主要内容,如果未能解决你的问题,请参考以下文章
Asp.Net MVC4 Web API - 我们是不是需要 OData 来构建快速查询服务
ASP .NET MVC 4 WebApi:手动处理 OData 查询
如何从 C# 控制器(OData)的 JSON 序列化中修复丢失的子对象(导航属性)?