本文转自:http://chris.eldredge.io/blog/2014/04/24/Composite-Keys/

In our basic configuration we told the model builder that our entity has a composite key comprised of an ID and a version:

1
2
3
4
5
6
7
8
9
10
public void MapDataServiceRoutes(HttpConfiguration config)
{
var builder = new ODataConventionModelBuilder(); var entity = builder.EntitySet<ODataPackage>("Packages");
entity.EntityType.HasKey(pkg => pkg.Id);
entity.EntityType.HasKey(pkg => pkg.Version); // snip
}

This is enough for our OData feed to render edit and self links for each individual entity in a form like:

http://localhost/odata/Packages(Id='Sample',Version='1.0.0')

But if we navigate to this URL, instead of getting just this one entity by key, we get back the entire entity set.

To get the correct behavior, first we need an override on our PackagesODataController that gets an individual entity instance by key:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class PackagesODataController : ODataController
{
public IMirroringPackageRepository Repository { get; set; } public IQueryable<ODataPackage> Get()
{
return Repository.GetPackages().Select(p => p.ToODataPackage()).AsQueryable();
} public IHttpActionResult Get(
[FromODataUri] string id,
[FromODataUri] string version)
{
var package = Repository.FindPackage(id, version); return package == null
? (IHttpActionResult)NotFound()
: Ok(package.ToODataPackage());
}
}

However, out of the box WebApi OData doesn’t know how to bind composite key parameters to an action such as this, since the key is comprised of multiple values.

We can fix this by creating a new routing convention that binds the stuff inside the parenthesis to our route data map:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class CompositeKeyRoutingConvention : IODataRoutingConvention
{
private readonly EntityRoutingConvention entityRoutingConvention =
new EntityRoutingConvention(); public virtual string SelectController(
ODataPath odataPath,
HttpRequestMessage request)
{
return entityRoutingConvention
.SelectController(odataPath, request);
} public virtual string SelectAction(
ODataPath odataPath,
HttpControllerContext controllerContext,
ILookup<string, HttpActionDescriptor> actionMap)
{
var action = entityRoutingConvention
.SelectAction(odataPath, controllerContext, actionMap); if (action == null)
{
return null;
} var routeValues = controllerContext.RouteData.Values; object value;
if (!routeValues.TryGetValue(ODataRouteConstants.Key,
out value))
{
return action;
} var compoundKeyPairs = ((string)value).Split(','); if (!compoundKeyPairs.Any())
{
return null;
} var keyValues = compoundKeyPairs
.Select(kv => kv.Split('='))
.Select(kv =>
new KeyValuePair<string, object>(kv[0], kv[1])); routeValues.AddRange(keyValues); return action;
}
}

This class decorates a standard EntityRoutingConvention and splits the raw key portion of the URI into key/value pairs and adds them all to the routeValues dictionary.

Once this is done the standard action resolution kicks in and finds the correct action overload to invoke.

This routing convention was adapted from the WebApi ODataCompositeKeySampleproject.

Here we see another difference between WebApi OData and WCF Data Services. In WCF Data Services, the framework handles generating a query that selects a single instance from an IQueryable. This limits our ability to customize how finding an instance by key is done. In WebApi OData, we have to explicitly define an overload that gets an entity instance by key, giving us more control over how the query is executed.

This distinction might not matter for most projects, but in the case of NuGet.Lucene.Web, it enables a mirror-on-demand capability where a local feed can fetch a package from another server on the fly, add it to the local repository, then send it back to the client as if it was always there in the first place.

To customize this in WCF Data Services required significant back flips.

Series Index

  1. Introduction
  2. Basic WebApi OData
  3. Composite Keys
  4. Default Streams

[转]Composite Keys With WebApi OData的更多相关文章

  1. [转]Web API OData V4 Keys, Composite Keys and Functions Part 11

    本文转自:https://damienbod.com/2014/09/12/web-api-odata-v4-keys-composite-keys-and-functions-part-11/ We ...

  2. OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service & Client

    一.概念介绍 1.1,什么是OData? 还是看OData官网的简单说明: An open protocol to allow the creation and consumption of quer ...

  3. AspNet WebApi OData 学习

    OData介绍:是一个查询和更新数据的Web协议.OData应用了web技术如HTTP.Atom发布协议(AtomPub)和JSON等来提供对不同应用程序,服务 和存储的信息访问.除了提供一些基本的操 ...

  4. AspNet.WebAPI.OData.ODataPQ

    AspNet.WebAPI.OData.ODataPQ实现WebAPI的分页查询服务 AspNet.WebAPI.OData.ODataPQ实现WebAPI的分页查询服务-(个人拙笔) AspNet. ...

  5. AspNet.WebAPI.OData.ODataPQ实现WebAPI的分页查询服务-(个人拙笔)

    AspNet.WebAPI.OData.ODataPQ 这是针对 Asp.net WebAPI OData 协议下,查询分页.或者是说 本人在使用Asp.Net webAPI 做服务接口时写的一个分页 ...

  6. 主攻ASP.NET MVC4.0之重生:Asp.Net MVC WebApi OData

    1.新建MVC项目,安装OData Install-Package Microsoft.AspNet.WebApi.OData -Version 4.0.0 2.新建WebAPI Controller ...

  7. AspNet.WebAPI.OData.ODataPQ实现WebAPI的分页查询服务-(个人拙笔)(转)

    出处:http://www.bubuko.com/infodetail-827612.html AspNet.WebAPI.OData.ODataPQ 这是针对 Asp.net WebAPI ODat ...

  8. [转]OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service & Client

    本文转自:http://www.cnblogs.com/bluedoctor/p/4384659.html 一.概念介绍 1.1,什么是OData? 还是看OData官网的简单说明: An open ...

  9. webAPi OData的使用

    一.OData介绍 开放数据协议(Open Data Protocol,缩写OData)是一种描述如何创建和访问Restful服务的OASIS标准. 二.OData 在asp.net mvc中的用法 ...

随机推荐

  1. 安装php环境

    安装xampp 安装zend studio 安装Composer-Setup 安装Z2 ZendFramework-2.4.9 I can install successfully using the ...

  2. 【总结】 BZOJ1000~1099板刷计划

    Tham又布置了一大堆题目,但是因为我TCL完全不会做,所以只能切切BZOJ的题目,划划水,要不是xz的面子大,我就已经被赶出了CJ信息组了QwQ(聂已己是神仙!) 1000 A+B这种入门题就不用写 ...

  3. java—不同的用户登录以后可以看到不同的菜单(后台可以实现对用户菜单的管理) 1 (55)

    实现不同的用户登录以后可以看到不同的菜单.(后台可以实现对用户菜单的管理.) 第一步:分析数据结构        1:用户表 表名:users 列名 类型 说明 id Varchar(32) 主键 n ...

  4. net项目总结一(1)

    中小型新闻发布系统 代码结构:分为实体层,数据层与接口,数据工厂层,业务逻辑层,公共层,UI层(由于图片上传实在麻烦,所以只上传少量而已),项目中用到了工厂模式,解耦BLL层和DLL层 1.登录功能, ...

  5. ASP.net/C#中如何调用动态链接库DLL

    动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL文 ...

  6. Java中Io流操作-File类的常用操作-创建文件,创建文件夹

    package com.hxzy.IOSer; import java.io.File;import java.io.IOException; public class Demo03 { public ...

  7. AngularJS入门讲解2:过滤器和双向绑定

    我们在上一课做了很多基础性的训练,接下来,我们讲一些难点的知识点,首先,讲一下如何实现一个全文检索功能: <html ng-app> <head> ... <script ...

  8. [Objective-C语言教程]命令行参数(23)

    执行时,可以将一些值从命令行传递给Objective-C程序. 这些值称为命令行参数,很多时候它们对程序很重要,特别是当想要从外部控制程序而不是在代码中对这些值进行硬编码时就很有用了. 命令行参数使用 ...

  9. 利用python 学习数据分析 (学习三)

    内容学习自: Python for Data Analysis, 2nd Edition         就是这本 纯英文学的很累,对不对取决于百度翻译了 前情提要: 各种方法贴: https://w ...

  10. php 内存分配新

    https://yq.aliyun.com/articles/38307 https://yq.aliyun.com/ziliao/132720 http://blog.liyiwei.cn/%E3% ...