通常情况下,一个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. 解决centos7下tomcat启动正常,无法访问项目的问题

    centos7防火墙不再采用iptables命令,改用firewalld 禁用防火墙命令: # systemctl stop firewalld.service # systemctl disable ...

  2. 一个简单的Java程序

    一个.NET技术还是很菜的水平的猿人现在要去学习Java不知道是坏是好,无从得知啊! 不过在网上看了好多Java方面的简单例子,感觉Java还是蛮不错的么!不管以后怎么样啦,先开始自己的Java菜鸟之 ...

  3. C# 特性(Attribute)详细介绍

    1.什么是Atrribute 首先,我们肯定Attribute是一个类,下面是msdn文档对它的描述:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注 ...

  4. 【linux】grep的使用

    最近发现了grep一个超级好用的指令 1. 在当前目录及其子目录中查找所有包含字符串abc的文件及位置 grep -rn "abc" * 2. 查找不包含"abc&quo ...

  5. MongoDB学习笔记-1

    mongod --dbpath D:\MogonDB3.4.10\db //开启数据库,无端口号mongod --dbpath D:\MogonDB3.4.10\db --port=10086 //开 ...

  6. MySQL锁分类

    相对其他数据库而言,MySQL的锁机制比较简单,基最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);BDB ...

  7. ZCTF-2017 比赛总结

    这次ZCTF办的还是相当不错的,至少对于Pwn来说是能够让人学习到一些东西. 第一天做的不是很顺利,一直卡在一道题上不动.第二天队友很给力,自己的思路也开阔起来了. 关于赛题的优点 我觉得这次的Pwn ...

  8. 判断js数组/对象是否为空

    /** * 判断js数组/对象是否为空 * isPrototypeOf() 验证一个对象是否存在于另一个对象的原型链上.即判断 Object 是否存在于 $obj 的原型链上.js中一切皆对象,也就是 ...

  9. Wireshark网络分析就这么简单

    tcpdump抓包命令: root#tcpdump -I eth0 -s 80 -w /tmp/tcpdump.cap 注:其中80表示,只抓每个包的前80个字节. 抓包时就筛选自己需要的包: Wir ...

  10. 玩转SpringCloud(F版本) 二.服务消费者(2)feign

    上一篇博客讲解了服务消费者的ribbon+restTemplate模式的搭建,此篇文章将要讲解服务消费者feign模式的搭建,这里是为了普及知识 平时的项目中两种消费模式选择其一即可 本篇博客基于博客 ...