通常情况下,一个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. java虚拟机规范(se8)——java虚拟机结构(三)

    2.6. 栈帧 栈帧用于存储数据和部分结果,同样也用于执行动态链接,返回方法的值和分派异常. 当方法被调用的时候会创建一个新的栈帧.当一个方法调用结束时,它对应的栈帧就被销毁了,不管是正常调用结束还是 ...

  2. asp.net 文件下载显示中文名称

    protected void Page_Load(object sender, EventArgs e)    {        string guid = Request.QueryString[& ...

  3. python多个分割符split字符串

    python中string自带的split不支持多个分隔符同时切分,用正则 import re line='hello,world' lineLists = re.split('[,,..??]',l ...

  4. Java编程的逻辑 (69) - 线程的中断

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  5. 如何写django中form的测试用例

    可简可繁, 可插库,可字符, 要测试valid,也要测试invalid, 可用csrf,也可用context. 放一个全面的, 实践中,找一个最优的组合就好. class NewTopicTests( ...

  6. ubuntu下root和安装mysql

    sudo password创建新的root密码: 1.用当前登录用户打开终端,在终端输入命令 sudo passwd,输入当前用户的密码然后回车 2.会提示输入新密码,输入完成后回车(http://w ...

  7. lrzsz安装

    当服务器没有安装FTP等工具上传文件时,可以通过rz上传文件,sz    文件名  进行下载文件,默认下载路径为: C:\Users\用户\Downloads,安装如下: yum install lr ...

  8. 028.Zabbix常见故障

    一 中文乱码处理 1.1 现象 1.2 解决方法 将任意一中文字体上传至/usr/share/zabbix/fonts,如微软雅黑. vi /usr/share/zabbix/include/defi ...

  9. 【python学习-4】可复用函数与模块

    1.自定义函数 自定义函数格式如下: def <函数名> (参数列表): <函数语句> return <返回值> #!/usr/bin/python # 定义函数, ...

  10. 循序渐进学.Net Core Web Api开发系列【5】:文件上传

    系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.概述 本篇介绍通 ...