考虑以下域模型:
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int AddressId { get; set; }
public Address Address { get; set; }
public ICollection<Message> Messages { get; set; }
}
public class Address
{
public int Id { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
.....
}
public class Message
{
public int Id { get; set; }
public Message Message { get; set; }
}
我们首先使用EF6代码为该模型创建数据库 . 地址数据保存到自己的表中 . 在EF6之上,我们使用ASP.NET Web API 2.0和OData . ODataConventionModelBuilder为Employee创建EntitySet,为Address创建ComplexType .
为了返回Employee,我们创建了以下操作:
[EnableQuery]
public SingleResult<Employee> Get([FromODataUri] int key)
为了始终返回地址,我们在Address属性上使用EF Include . 所以当我们使用以下网址时:
/api/Employees(1)
将返回ID为1的Employee并填充其Address属性 .
但是,当我们使用 $expand
扩展消息以供使用时,我们会松开地址数据:
/api/Employee(1)?$expand=Messages
返回一个扩展了Messages的Employee对象,但没有Address数据 . EnableQuery
属性将扩展应用于我们的查询,但会覆盖我们在API中指定的EF包含 . 我们也无法从客户端扩展Address,因为无法在OData中扩展Complex类型 . 当我们将Address Odata类型更改为Entity时,我们需要多次调用来创建或更新Employee . 一次调用地址控制器,它处理地址的创建/更新,一次调用Employee控制器来处理员工的创建/更新 .
So my question :是否可以保留地址包含而无需从客户端指定?
1 回答
我们在选择所有属性时使用像Employee这样的元素类型,因此在编写Linq表达式时我们会丢失包含地址,但如果选择地址,则会出现结果,因为它不是全部选择,因此可能需要处理以下内容:$ expand =消息&$选择=地址,身份证,姓名
相关代码:https://github.com/OData/WebApi/blob/master/OData/src/System.Web.OData/OData/Query/Expressions/SelectExpandBinder.cs#L272-L292