WebAPI OData操作示例 - CheckOut和CheckOutMany操作之间的区别

时间:2013-07-23 07:02:59

标签: c# asp.net asp.net-web-api odata

我一直在忙着对T4模板进行自定义,以便我可以从.NET客户端进行强类型的OData动作调用。它可能是我创建的第一个开源的东西:)

无论如何,我正在测试和开发针对称为“ODataActionsSample”的OData操作的WebAPI OData示例。对于那些想在家里玩的人,你可以在http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/ODataActionsSample/找到样品。

该示例还有几个有趣的操作。目前我正在尝试支持这两个基于集合的操作,因为我已经控制了其他操作。这两个操作是CheckOut操作(接受$ filter查询的覆盖)和CheckOutMany操作(接受电影ID的集合)。

示例代码......

        // CheckOut action
        // URI: ~/odata/Movies/CheckOut
        // Shows how to bind to a collection, instead of a single entity.
        // This action also accepts $filter queries. For example:
        //     ~/odata/Movies/CheckOut?$filter=Year eq 2005
        var checkOutFromCollection = modelBuilder.Entity<Movie>().Collection.Action("CheckOut");
        checkOutFromCollection.ReturnsCollectionFromEntitySet<Movie>("Movies");

        // CheckOutMany action
        // URI: ~/odata/Movies/CheckOutMany
        // Shows an action that takes a collection parameter.
        ActionConfiguration checkoutMany = modelBuilder.Entity<Movie>().Collection.Action("CheckOutMany");
        checkoutMany.CollectionParameter<int>("MovieIDs");
        checkoutMany.ReturnsCollectionFromEntitySet<Movie>("Movies");

为这些生成的元数据几乎相同。它是

    <FunctionImport Name="CheckOut" ReturnType="Collection(ODataActionsSample.Models.Movie)" IsBindable="true" EntitySet="Movies" m:IsAlwaysBindable="true">
      <Parameter Name="bindingParameter" Type="Collection(ODataActionsSample.Models.Movie)" Nullable="false" />
    </FunctionImport>
    <FunctionImport Name="CheckOutMany" ReturnType="Collection(ODataActionsSample.Models.Movie)" IsBindable="true" EntitySet="Movies" m:IsAlwaysBindable="true">
      <Parameter Name="bindingParameter" Type="Collection(ODataActionsSample.Models.Movie)" Nullable="false" />
      <Parameter Name="MovieIDs" Type="Collection(Edm.Int32)" Nullable="false" />
    </FunctionImport>

正如您在示例的注释中所看到的,调用每个的URI非常不同,但元数据中并没有任何线索表明CheckOut操作接受的基本上是IQueryable而不是{{{ 1}}接受一组MovieID的动作。是的我看到CheckOutMany动作有额外的参数,但在我看来它不应该有一个BindingParameter条目。

我想我可以有一个启发式来接受这种情况 - 我们接受一个BindingParameter,它是一个集合,但是也接受一个集合,该集合包含与感兴趣的实体单键类型匹配的基元(在这种情况下)那是CheckOutMany)。坦率地说,这有点不稳定,但它至少会起作用。

直接提问(但对上述评论非常感谢!)

a)这是唯一可行的方法(即制作启发式方法)吗?

b)我们是否可以更改“ActionConfiguration”设置,以使int不会绑定到与CheckOutMany相同的集合?

c)或者这是一个设计缺陷,错误还是仅仅尚未完全烘焙的功能?

1 个答案:

答案 0 :(得分:0)

您对CheckOutMany的观察是正确的。 CheckOutMany绑定到实体集合是没有意义的,因为它已经将影片ID作为输入检出。