odata php,[转]Composite Keys With WebApi OData

本文转自: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:

public void MapDataServiceRoutes(HttpConfiguration config)

{

var builder = new ODataConventionModelBuilder();

var entity = builder.EntitySet("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:

public class PackagesODataController : ODataController

{

public IMirroringPackageRepository Repository { get; set; }

public IQueryable 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:

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 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(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

Introduction

Basic WebApi OData

Composite Keys

Default Streams

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值