通常情况下,一个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. urb传输的代码分析【转】

    转自:http://blog.csdn.net/zkami/article/details/2503829 urb传输的代码分析 如需引用,请注明出处blog.csdn.net/zkami 作者Zhe ...

  2. innobackupex不停库的数据备份并恢复到别的服务器上【转】

    1.innobackupex原理: 备份原理 1).首先会开启一个后台检测进程,实时检测myql redo的变化,一旦发现redo中有新日志写入,立即将日志记入后台日志文件xtrabackup_log ...

  3. C# 每月第一天和最后一天

    //每月第一天 - DateTime.Now.Day); //每月最后一天 var endTime=DateTime.Now.AddDays(1 - DateTime.Now.Day).AddMont ...

  4. Java封装概述

    1.封装概述 private  public 2.实现封装 例子: package com.java1995; public class Student { private String name; ...

  5. 5 个 Laravel Eloquent 小技巧

    1. 快速生成 Model & Migration 这并不是一个很多人知道的小技巧,为文章生成 Model 和 Migration. $ php artisan make:migration ...

  6. R语言学习笔记:使用tcltk包显示进度条

    一般在跑耗时较长的程序时,我们不知道程序到底有没有正常跑着,或者在爬虫的时候不知道爬到什么时候断了.因此可以添加进度条来显示当前进度,观察进度是否有进展.当进度条卡住的时候,可以判断程序断线,从而可以 ...

  7. Android多开/分身检测

    原文:https://blog.darkness463.top/2018/05/04/Android-Virtual-Check/ 多开/分身原本用于方便有多个微信/QQ解决同时登录的问题,但近来年被 ...

  8. MyEclipse如何查找指定工程下所有或指定文件中特定字符串并且可进行批量替换

    查找操作步骤:(1)在myEclipse里菜单选择-Search-Search(快捷键:ctrl+h);(2)在弹出对话框中选File Search选项,然后在第一个文本框中输入“要查找的字符串”(为 ...

  9. ASP.Net1

    一.Web应用程序与传统桌面应用程序的不同: 1.产品级的Web应用程序总是包括至少两台联网的机器:一台承载网站,另一台在Web浏览器中查看数据. 即:我们通过自己的电脑浏览Web程序,这个程序会向服 ...

  10. CentOS7.x使用overlay文件系统

    https://www.cnblogs.com/yufeng218/p/8370670.html http://www.cnblogs.com/lehuoxiong/p/9908118.html ht ...