WCF Data Servicesの記事を見ると、どれもEntity FrameworkのObjectContextやDbContextをベースにしたクラスを前提にしているものが多いので、ここではあえてリフレクションプロバイダーを使って頑張ってみようと思います。リフレクションプロバイダーを使うと以下のようなイメージのことが出来ると信じてます。
これが出来なかったら悲しみますはい。
リフレクションプロバイダーとは
WCF Data Servicesのリフレクションプロバイダーは、IQueryable
namespace WebApplication1 { using System.Collections.Generic; using System.Data.Services; using System.Data.Services.Common; using System.Linq; public class WcfDataService : DataService<SampleContext> { public static void InitializeService(DataServiceConfiguration config) { config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3; } } // PersonとAddressを公開するクラス public class SampleContext { public IQueryable<Person> People { get { return Person.Source.AsQueryable(); } } public IQueryable<Address> Addresses { get { return Person.Source.Select(p => p.Address).AsQueryable(); } } } [DataServiceKey("Id")] public class Person { // テスト用データ public static readonly List<Person> Source = Enumerable.Range(1, 10) .Select(i => new Person { Id = i, Name = "test data " + i, Address = new Address { Id = i, City = "test city " + i } }) .ToList(); public int Id { get; set; } public string Name { get; set; } public Address Address { get; set; } } [DataServiceKey("Id")] public class Address { public int Id { get; set; } public string City { get; set; } } }
WcfDataService.svcを開始ページに設定してアプリケーションを実行すると、以下のようなXMLが表示されます。
<?xml version="1.0" encoding="utf-8"?> <service xml:base="http://localhost:49533/WcfDataService.svc/" xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom"> <workspace> <atom:title>Default</atom:title> <collection href="People"> <atom:title>People</atom:title> </collection> <collection href="Addresses"> <atom:title>Addresses</atom:title> </collection> </workspace> </service>
この状態で、ODataのクエリを投げるとちゃんとデータが取れる状態にまでなってます。例えば” http://localhost:49533/WcfDataService.svc/People(1)?$expand=Address”のようなURLにGETをすると以下のようなデータが返ってきます。
<?xml version="1.0" encoding="utf-8"?> <entry xml:base="http://localhost:49533/WcfDataService.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> <id>http://localhost:49533/WcfDataService.svc/People(1)</id> <category term="WebApplication1.Person" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <link rel="edit" title="Person" href="People(1)" /> <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Address" type="application/atom+xml;type=entry" title="Address" href="People(1)/Address"> <m:inline> <entry> <id>http://localhost:49533/WcfDataService.svc/Addresses(1)</id> <category term="WebApplication1.Address" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <link rel="edit" title="Address" href="Addresses(1)" /> <title /> <updated>2012-10-02T11:50:11Z</updated> <author> <name /> </author> <content type="application/xml"> <m:properties> <d:Id m:type="Edm.Int32">1</d:Id> <d:City>test city 1</d:City> </m:properties> </content> </entry> </m:inline> </link> <title /> <updated>2012-10-02T11:50:11Z</updated> <author> <name /> </author> <content type="application/xml"> <m:properties> <d:Id m:type="Edm.Int32">1</d:Id> <d:Name>test data 1</d:Name> </m:properties> </content> </entry>
公開だけならとってもお手軽なんですよね。さて、ここにロジックを挟み込んでみようと思うのが本題…。ちょっと悩もう。