OData扩展覆盖实体框架包括

时间:2015-10-16 07:13:09

标签: c# entity-framework odata asp.net-web-api2

考虑以下域模型:

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的员工,其地址属性已填写。

但是,当我们使用$expand展开使用的消息时,我们会松开地址数据:

/api/Employee(1)?$expand=Messages

返回一个扩展了Messages的Employee对象,但没有Address数据。 EnableQuery属性将扩展应用于我们的查询,但会覆盖我们在API中指定的EF包含。 我们也无法从客户端扩展Address,因为无法在OData中扩展Complex类型。 当我们将Address Odata类型更改为Entity时,我们需要多次调用来创建或更新Employee。一次调用地址控制器,它处理地址的创建/更新,一次调用Employee控制器来处理员工的创建/更新。

所以我的问题:是否可以在不指定客户端的情况下保留地址包含?

1 个答案:

答案 0 :(得分:0)

我们在选择所有属性时使用像Employee这样的元素类型,因此在编写Linq表达式时我们会丢失包含地址,但如果选择地址,则会出现结果,因为它不是全部选择,所以工作可能请求如下:$ expand = Messages&amp; $ select = Address,Id,Name

相关代码:https://github.com/OData/WebApi/blob/master/OData/src/System.Web.OData/OData/Query/Expressions/SelectExpandBinder.cs#L272-L292