通常情况下,一个OData的EDM(Entity Data Model)在配置的时候定义了,才可以被查询或执行各种操作。比如如下:

builder.EntitySet<SomeModel>("SomeModels");

可能会这样查询:http://localhost:8888/odata/SomeModels

如果SomeModel中有一个集合导航属性,该如何获取呢?比如:

public class SomeModel
{
public int Id{get;set;} public IList<AnotherModel> AnotherModels{get;set;}
} public class AnotherModel
{

我们是否可以直接在SomeModel中获取所有的AnotherModel, 而不是通过如下方式获取:

builder.EntitySet<AnotherModel>("AnotherModels");
http://localhost:8888/odata/AnotherModels

OData为我们提供了Containment,只要为某个集合导航属性加上[Contained]特性,就可以按如下方式获取某个EDM模型下的集合导航属性,比如:

http://localhost:8888/odata/SomeModels(1)/AnotherModels

好先定义模型。

public class Account
{
public int AccountID { get; set; }
public string Name { get; set; } [Contained]
public IList<PaymentInstrument> PayinPIs { get; set; }
} public class PaymentInstrument
{
public int PaymentInstrumentID { get; set; }
public string FriendlyName { get; set; }
}

以上,一旦在PayinPIs这个集合导航属性上加上[Contained]特性,只要在controller中再提供获取集合导航属性的方法,我们就可以按如下方式,通过Account获取PaymentInstrument集合。如下:

http://localhost:8888/odata/Accounts(100)/PayinPIs

在WebApiConfig类中定义如下:

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
... config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: GetModel());
} private static IEdmModel GetModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntityType<PaymentInstrument>();
builder.EntitySet<Account>("Accounts"); return builder.GetEdmModel();
}
}

在API端定义如下:

public class AccountsController : ODataController
{ private static IList<Account> _accounts = null; public AccountsController()
{
if(_accounts==null)
{
_accounts = InitAccounts();
}
} [EnableQuery]
public IHttpActionResult Get()
{
return Ok(_accounts.AsQueryable());
} [EnableQuery]
public IHttpActionResult GetById([FromODataUri] int key)
{
var account = _accounts.Single(a => a.AccountID == key);
return Ok(account);
} //获取Account所有的PaymentInstrument集合
[EnableQuery]
public IHttpActionResult GetPayinPIs([FromODataUri]int key)
{
var payinPIs = _accounts.Single(a => a.AccountID == key).PayinPIs;
return Ok(payinPIs);
} private static IList<Account> InitAccounts()
{
var accounts = new List<Account>()
{
new Account()
{
AccountID = ,
Name="Name100",
PayoutPI = new PaymentInstrument()
{
PaymentInstrumentID = ,
FriendlyName = "Payout PI: Paypal",
},
PayinPIs = new List<PaymentInstrument>()
{
new PaymentInstrument()
{
PaymentInstrumentID = ,
FriendlyName = "101 first PI",
},
new PaymentInstrument()
{
PaymentInstrumentID = ,
FriendlyName = "102 second PI",
},
},
},
};
return accounts;
}
}

以上的GetPayinPIs方法可以让我们根据Account获取其集合导航属性PayinPIs。

好,现在PayinPIs加上了[Contained]特性,也配备了具体的Action,现在开始查询:

http://localhost:64696/odata/Accounts(100)/PayinPIs

能查询到所有的PaymentInstrument。

此时,PayinPIs集合导航属性在元数据中是如何呈现的呢?查询如下:

http://localhost:64696/odata/$metadata

相关部分为:

<EntityType Name="Account">
<Key>
<PropertyRef Name="AccountID" />
</Key>
<Property Name="AccountID" Type="Edm.Int32" Nullable="false" />
<Property Name="Name" Type="Edm.String" />
<NavigationProperty Name="PayinPIs" Type="Collection(MyODataContainmentSample.PaymentInstrument)" ContainsTarget="true" />
</EntityType>

如果把PayinPIs上的[Contained]特性去掉呢?去掉后再次查询如下:

http://localhost:64696/odata/Accounts(100)/PayinPIs

返回404 NOT FOUND

再来看去掉[Contained]特性后相关的元数据:

<NavigationProperty Name="PayinPIs" Type="Collection(MyODataContainmentSample.PaymentInstrument)" />

没去掉[Contained]特性之前是:
<NavigationProperty Name="PayinPIs" Type="Collection(MyODataContainmentSample.PaymentInstrument)" ContainsTarget="true" />

原来,在一个集合导航属性上添加[Contained]特性,实际是让ContainsTarget="true",而默认状况下,ContainsTarget="false"。

^_^

在ASP.NET Web API中使用OData的Containment的更多相关文章

  1. ASP.NET Web API中使用OData

    在ASP.NET Web API中使用OData 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在ASP.NET Web API中,对于CRUD(creat ...

  2. 在ASP.NET Web API中使用OData

    http://www.alixixi.com/program/a/2015063094986.shtml 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在A ...

  3. 在ASP.NET Web API中使用OData的Action和Function

    本篇体验OData的Action和Function功能.上下文信息参考"ASP.NET Web API基于OData的增删改查,以及处理实体间关系".在本文之前,我存在的疑惑包括: ...

  4. [翻译]在ASP.NET Web API中通过OData支持查询和分页

    OData可以通过形如http://localhost/Products?$orderby=Name这样的QueryString传递查询条件.排序等.你可以在任何Web API Controller中 ...

  5. 在ASP.NET Web API中使用OData的单例模式

    从OData v4开始增加了对单例模式的支持,我们不用每次根据主键等来获取某个EDM,就像在C#中使用单例模式一样.实现方式大致需要两步: 1.在需要实现单例模式的导航属性上加上[Singleton] ...

  6. ASP.NET Web API中的Controller

    虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...

  7. ASP.NET Web API 中的异常处理(转载)

    转载地址:ASP.NET Web API 中的异常处理

  8. 【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化

    谨以此文感谢关注此系列文章的园友!前段时间本以为此系列文章已没多少人关注,而不打算继续下去了.因为文章贴出来之后,看的人似乎不多,也很少有人对这些文章发表评论,而且几乎无人给予“推荐”.但前几天有人询 ...

  9. Asp.Net Web API 2第十三课——ASP.NET Web API中的JSON和XML序列化

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...

随机推荐

  1. .gitkeep

    看一个开源项目中有个.gitkeep文件,不知道是干嘛用的查询知道 git是不允许提交一个空的目录到版本库上的,可以在空的文件夹里面建立一个.gitkeep文件,然后提交去即可. 其实在git中 .g ...

  2. PHP回调函数及匿名函数概念与用法详解

    1.回调函数 PHP的回调函数其实和C.Java等语言的回调函数的作用是一模一样的,都是在主线程执行的过程中,突然跳去执行设置的回调函数: 回调函数执行完毕之后,再回到主线程处理接下来的流程 而在ph ...

  3. MVC5使用EF6 Code First--创建EF数据模型(一)

    此Web应用程序演示如何使用Entity Framework 6和Visual Studio 2015创建ASP.NET MVC 5应用程序.本教程使用“Code First ”即代码先行.有关如何在 ...

  4. 【Unity_UWP】Unity 工程发布win10 UWP 时的本地文件读取 (下篇)

    Universal Windows Platform(UWP)是微软Windows10专用的通用应用平台,其目的在于在统一操作系统下控制所有智能电子设备. 自从Unity 5.2之后,配合VS 201 ...

  5. c run-time library 和 standard c++ library

    参考: c run-time libraries:  http://msdn.microsoft.com/zh-cn/library/vstudio/abx4dbyh(v=vs.100).aspx H ...

  6. 自定义yum源

    1.创建rpm包的存放目录 mkdir  -p   /yum/yum-sum/package 2.准备rpm包,可以通过自带yum只下载不安装工具下载 yum install --downloadon ...

  7. 【BZOJ】1294: [SCOI2009]围豆豆Bean

    题解 随机跳题真好玩 这个就是考虑我们怎么判断点在多边形内,就是点做一条射线,穿过了奇数条边 我们只需要记录一个二进制状态表示每个点的射线穿过路径的次数的奇偶性 枚举起点,然后用BFS的方式更新dp状 ...

  8. 【Java】 大话数据结构(9) 树(二叉树、线索二叉树)

    本文根据<大话数据结构>一书,对Java版的二叉树.线索二叉树进行了一定程度的实现. 另: 二叉排序树(二叉搜索树) 平衡二叉树(AVL树) 二叉树的性质 性质1:二叉树第i层上的结点数目 ...

  9. [过程记录]Centos7 下 Hadoop分布式集群搭建

    过程如下: 配置hosts vim /etc/hosts 格式: ip hostname ip hostname 设置免密登陆 首先:每台主机使用ssh命令连接其余主机 ssh 用户名@主机名 提示是 ...

  10. jenkins 整合maven,svn(配置钩子程序实现提交代码自动构建),tomcat实现热部署(windows+linux分别实现)

    springboot : https://blog.csdn.net/zjh_746140129/article/details/80904876 1 准备工作: (1)运行jenkins的tomca ...