OData

ODataとは 「Webアプリケーションにおけるデータアクセス方法を標準化したプロトコル」です。Microsoft、IBM、SAP、Citrix社など中心となり仕様が策定され、2014年3月に国際標準化団体OASIS(Organization for the Advancement of Structured Information Standards, 構造化情報標準促進協会)によりOData 4.0が標準化されています。

ForguncyはOData、およびODataのリソースパスを使用したテーブルデータの取得のみをサポートしています。また、ODataの一部のクエリオプション、演算子、関数をサポートしています。ODataを使ったデータの取得方法には、以下の4種類の方法があります。

サーバーサイドAPI

GetTableData メソッド (String)オーバーロードを使用することで、ODataのリソースパスを使ってテーブルデータを取得できます。

Web API

getTableDataByODataメソッドを使用することで、ODataのリソースパスを使ってテーブルデータを取得できます。詳細はレコードの取得を参照してください。

URL

以下のようなURLのルールで、ODataを使用したテーブルデータの取得が行えます。

http://<サーバー名、またはIPアドレス>/<アプリケーションパス>/OData/GetData/<ODataのリソースパス>

たとえば、サーバー名が「srv01」、アプリケーション名が「app01」である場合に、「Categories」テーブルの「CategoryID」フィールドの値が「2」のレコードを取得するURLは以下のようになります。

http://srv01/app01/OData/GetData/Categories?$filter=CategoryID eq 2

なお、Forguncyアプリケーションにログインしていない場合には、URLを使用した方法は使用できません。以下にC#コードを使用してForguncyアプリケーションの認証を取得し、URLによるODataを使用したテーブルデータの取得例を示します。

public string GetOData(string baseUrl, string odataParam, CookieContainer loginCookie)
{
    HttpWebRequest rq = HttpWebRequest.Create(baseUrl + "OData/GetData/" + odataParam) as HttpWebRequest;
    rq.CookieContainer = loginCookie;
    rq.Method = WebRequestMethods.Http.Get;
    var response = rq.GetResponse();
    return new StreamReader(response.GetResponseStream()).ReadToEnd();
}
CookieContainer GetLoginCookie(string baseUrl, string userName, string passWord)
{
    var login = baseUrl + "Account/Login";
    HttpWebRequest rq = HttpWebRequest.Create(login) as HttpWebRequest;
    rq.CookieContainer = new CookieContainer();
    rq.Method = WebRequestMethods.Http.Post;
    rq.Accept = "application/json";
    rq.ContentType = "application/json";
    var loginStr = "{userName:\"" + userName + "\", password:\"" + passWord + "\",rememberMe:true }";
    var data = Encoding.UTF8.GetBytes(loginStr);
    using (Stream stream = rq.GetRequestStream())
    {
        stream.Write(data, 0, data.Length);
    }
    var response = rq.GetResponse();
    return rq.CookieContainer;
}
 
//テストコード
var baseUrl = "http://localhost:42515/Forguncy/";
var loginCookie = GetLoginCookie(baseUrl, "Administrator", "123456");
Console.WriteLine(GetOData(baseUrl, "table", loginCookie));
Console.WriteLine(GetOData(baseUrl, "table(2)", loginCookie));

 

public static string GetODataWindows(string baseUrl, string odataParam, string userName, string password, string domain)
{
    HttpWebRequest rq = HttpWebRequest.Create(baseUrl + "OData/GetData/" + odataParam) as HttpWebRequest;
    rq.Credentials = new NetworkCredential(userName,password, domain); 
    rq.Method = WebRequestMethods.Http.Get;
    var response = rq.GetResponse();
    return new StreamReader(response.GetResponseStream()).ReadToEnd();
}
 
// テストコード
Console.WriteLine(GetOData(baseUrl, "table", "budoutaro", "123456","abccompany"));

 

関数

Excelには存在しないForguncy固有の関数としてODATA関数を提供しています。ODATAを使用することで、ODataのリソースパスを使ってテーブルデータを取得できます。なお、ODATA関数はリストビュー上のセルでは使用できません。

「Categories」テーブルの「CategoryID」フィールドの値が「2」のレコードを取得する場合の数式は以下のようになります。

=ODATA("Categories?$filter=CategoryID eq 2")

上記の場合で、値「2」の部分をA1セルの値で置き換えたい場合の数式は以下のようになります。

=ODATA("Categories?$filter=CategoryID eq " & A1)

ODATA関数を使って複数レコードのデータを表示したい場合、配列数式と組み合わせることで実現可能です。詳しくは配列数式を使用するを参照してください。

ODataの具体例

このようなODataのURLをForguncyがサポートする4種類の方法で表現した場合、以下のようになります。

サーバーサイドAPI(C#)

this.DataAccess.GetTableData("Categories(1)/Products?$top=2&$orderby=Name");

Web API(JavaScript)

Forguncy.getTableDataByOData("Categories(1)/Products?$top=2&$orderby=Name", function (data) { }, function (e) { });

URL(サーバー名が「srv01」、アプリケーション名が「app01」である場合)

http://srv01/app01/OData/GetData/Categories(1)/Products?$top=2&$orderby=Name

関数

=ODATA("Categories(1)/Products?$top=2&$orderby=Name")

 

以下に代表的な具体例を示します。記載する具体例は「リソースパス」以降の部分のみです。

●基本的なクエリ

括弧を使用して評価の優先順位を制御した場合を除き、各クエリオプションの評価順序はSQLにおけるselect文の評価順序に従います。クエリオプションの並び順は関係しませんので、注意してください。

Categories

「Categories」テーブルの全データを取得します。

Categories(4)

主キーであるフィールドが4のレコードを「Categories」テーブルから取得します。

OrderDetails(OrderID=10000,ProductID=17)

主キーである「OrederID」フィールドが10000、「ProductID」が17のレコードを「Categories」テーブルから取得します。

Categories(4)/CategoryName

「Categories」テーブルで主キーのフィールドが4であるレコードの「CategoryName」フィールドの値を取得します。

Categories(4)/CategoryName/$value

「Categories」テーブルで主キーのフィールドが4であるレコードの「CategoryName」フィールドの値を取得します。

●filterオプション

Categories?$filter=CategoryName eq 'Produce'

「Categories」テーブルで「CategoryName」フィールドの値が'Produce'であるレコードを取得します。

Categories?$filter=CategoryName eq 'Produce' and CategoryID le 2

「Categories」テーブルで「CategoryName」フィールドの値が'Produce'、かつ「CategoryID」が2以下であるレコードを取得します。

Categories?$filter=contains(CategoryName,'Pro')

「Categories」テーブルで「CategoryName」フィールドの値に'Pro'という文字列が含まれるレコードを取得します。

Categories?$filter=CategoryName eq 'Beverages' or (CategoryID lt 4 and CategoryID gt 1) or startswith(CategoryName,'Con')

「Categories」テーブルで「CategoryName」フィールドの値が'Beverages'のレコード、もしくは「CategoryID」フィールドの値が4よりも小さくかつ1よりも大きい、もしくは 「CategoryName」フィールドの値に'Con'という文字列が含まれるレコードを取得します。

Orders?$filter=OrderDate ge 1994-03-30"

「Orders」テーブルで「OrderDate」フィールドの値が1994/3/30と同じか、またはそれよりも新しい日付であるレコードを取得します。

Orders?$filter=year(OrderDate) gt 1994 and month(OrderDate) ge 1 and month(OrderDate) le 3

「Orders」テーブルで「OrderDate」フィールドの値が1994以降の年の第一四半期(1月から3月)のレコードを取得します。

●selectオプション

Categories?$select=CategoryName,CategoryID

「Categories」テーブルで「CategoryName」フィールドと「CategoryID」フィールドの全レコードを取得します。

Categories(1)?$select=CategoryName,CategoryID

「Categories」テーブルで主キーである「CategoryID」が1であるレコードの「CategoryName」フィールドと「CategoryID」フィールドの値のみを取得します。

Categories?$select=*

Categoriesテーブルにあるすべてのフィールドの全レコードを取得します。

Categories?$select=CategoryName,CategoryID&$filter=not startswith(CategoryName, 'Con')

「Categories」テーブルで「CategoryName」フィールドの値が'Con'という文字列から始まらないレコードの「CategoryName」フィールドと「CategoryID」フィールドの値のみを取得します。

●topオプション

Categories?$top=3

「Categories」テーブルで先頭行から3レコードのデータを取得します。

Categories?$top=3&$filter=CategoryID gt 3

「Categories」テーブルで「CategoryID」が3より大きいレコードに対して、先頭行から3レコードを取得します。

●orderbyオプション

Employees?$orderby=FirstName

「Employees」テーブルで「FirstName」フィールドをキーとして昇順で並べ替えを行った状態の全レコードを取得します。

Employees?$orderby=HireDate asc,LastName desc,FirstName desc

「Employees」テーブルで「HireDate」フィールドをキーとして昇順で並べ替え、その後それを「LastName」フィールドをキーとして降順で並べ替え、最後にそれを「FirstName」フィールドをキーとして降順で並べ替えを行った状態の全レコードを取得します。

Categories?$orderby=CategoryID desc&$filter=CategoryID lt 5

「Categories」テーブルで「CategoryID」フィールドの値が5よりも小さいレコードのみを抽出し、さらに「CategoryID」フィールドをキーとして降順で並べ替えたレコードを取得します。

Employees?$orderby=HireDate asc&$top=5

「Employees」テーブルで「HireDate」フィールドをキーとして降順で並べ替え、その先頭から5レコードを取得します。

Categories?$orderby=CategoryID desc&$filter=CategoryID le 2&$top=1

「Categories」テーブルで「CategoryID」フィールドの値が2以下のレコードのみを抽出し、「CategoryID」フィールドをキーとして降順で並べ替え、その中の先頭1件のレコードを取得します

●Countオプション

Categories/$count

「Categories」テーブルのレコード数を取得します。

Categories/$count?$filter=CategoryID lt 10

「Categories」テーブルにて「CategoryID」フィールドの値が10より少ないレコードの数を取得します。

●expand

Products?$expand=Categories

「Products」テーブルの全レコードを関連する「Categories」テーブルのレコードを含めた形で取得します。

Orders?$expand=Customers,Employees

「Orders」テーブルの全レコードを関連する「Customers」テーブルのレコードと「Employees」テーブルのレコードを含めた形で取得します。

Products?$expand=Categories($select=Description)

「Products」テーブルの全レコードを関連する「Categories」テーブルの「Description」フィールドのみを含めた形で取得します。

Orders?$expand=Customers($select=CompanyName,ContactName),Employees($select=Title)

「Orders」テーブルの全レコードを関連する「Customers」テーブルの「CompanyName」フィールドと「ContactName」フィールド、「Employees」テーブルの「Title」フィールドを含めた形で取得します。

OrderDetails?$expand=Products($select=ProductName,Categories)

「OrderDetails」テーブルの全レコードを関連する「Products」テーブルの「ProductName」フィールド、「Categories」テーブルのレコードを含めた形で取得します。

Products?$select=ProductName,Categories

Products?$expand=Categories&$select=ProductName,Categories

Products?$expand=Categories&$select=ProductName

「Products」テーブルの「ProductName」フィールドのみの全レコードとそれに関連する「Categories」テーブルのレコードを含めた形で取得します。上記の3つは、すべて同じ結果を返します。

Orders?$select=OrderID,Customers,Employees

「Orders」テーブルの「OrderID」フィールドのみの全レコードとそれに関連する「Customers」テーブルと「Employees」テーブルのレコードを含めた形で取得します。

Products?$expand=Categories($select=CategoryName)&$select=ProductName

「Products」テーブルの「ProductName」フィールドのみの全レコードとそれに関連する「Categories」テーブルの「CategoryName」フィールドのみのレコードを含めた形で取得します。

OrderDetails?$expand=Products($select=ProductName,Categories)&$filter=Products/Categories/CategoryName eq 'Produce'

「OrderDetails」テーブルと関連する「Product」の「ProductName」フィールドのみのレコード、さらにそれに関連する「Categories」テーブルのレコードで、「CategoryName」フィールドの値が'Produce'であるレコードのみを取得します。

OrderDetails?$expand=Products($select=ProductName,Categories)&$filter=Products/Categories/CategoryName eq 'Produce'&$orderby=Products/ProductName desc,OrderID asc

「OrderDetails」テーブルで関連する「Products」テーブルの「ProductName」フィールドのみのレコード、さらにそれに関連する「Categories」テーブルのレコードで、「CategoryName」フィールドの値が'Produce'であるレコードのみを「Products」テーブルの「ProductName」フィールドをキーとして降順で並べ替え、その後「OrderID 」フィールドをキーとして並べ替えたレコードを取得します。

●特定レコードの関連テーブルのデータ取得

Products(1)/Categories

「Products」テーブルの「ProductID」フィールドの値が1であるレコードに関連する「Categories」テーブルのレコードを取得します。

OrderDetails(OrderID = 10000, FK_ProductID = 17)/Products/Categories/CategoryName

「OrderDetails」テーブルの「OrderID」フィールドの値が10000であり、かつ「ProductID」フィールドの値が17であるレコードに関連する「Products」テーブルのレコードで、さらにそのレコードに関連する「Categories」テーブルの「CategoryName」フィールドの値のみを含むレコードを取得します。

Products(1)/Categories/CategoryName/$value

Products」テーブルの「ProductID」フィールドの値が1であるレコードに関連する「Categories」テーブルの「CategoryName」フィールドの値を取得します。

Products?$filter=Categories/CategoryName eq 'Produce'

「Products」テーブルで関連する「Categories」テーブルの「CategoryName」フィールドの値が'Produce'であるレコードを取得します。

OrderDetails?$filter=Products/Categories/CategoryName eq 'Produce'

「OrderDetails」テーブルで関連する「Products」テーブルから、さらに関連する「Categories」テーブルの「CategoryName」フィールドの値が'Produce'であるレコードを取得します。

Orders?$filter=Customers/CompanyName eq 'Franchi S.p.A.' and Employees/EmployeeID lt 10

「Orders」テーブルで関連する「Customers」テーブルの「CompanyName 」フィールドの値が'Franchi S.p.A.'で、かつ関連する「Employees」テーブルの「EmployeeID」フィールドの値が10より少ないレコードを取得します。

サポートされる演算子や関数

ForguncyのODataでは、以下の演算子や関数がサポートされます。

●論理演算子

演算子

説明

eq

等号

Accounts?$filter=City eq '仙台'

ne

不等号

Accounts?$filter=City ne null

gt

より大きい

Accounts?$filter=SupportIncidents/Value gt 1000

ge

以上

Accounts?&$filter=SupportIncidents/Value ge 1000

lt

より小さい

Accounts?$filter=SupportIncidents/Value lt 1000

le

以下

Accounts?$filter=SupportIncidents/Value le 1000

and

論理積

Accounts?$filter=SupportIncidents/Value ge 1000 andPrefecture eq '宮城'

or

論理和

Accounts?$filter=AccountCategoryCode/Value eq 2 or AccountRank/Value eq 1

not

論理否定

Accounts?$filter=(AccountCategoryCode/Value ne null) and not (AccountCategoryCode/Value eq 1)

 

●グループ化演算子

演算子

説明

()

式での評価の優先順位を制御します。

Products?$filter=(Price sub 5) gt 10

 

●関数

関数

説明

contains/not contains

指定した文字列を含むかどうかを返します。

startswith/not startswith

指定した文字列で始まるかどうかを返します。

endswith/not endswith

指定した文字列で終わるかどうかを返します。

year

指定した日付の年を返します。

month

指定した日付の月を返します。

day

指定した日付の日を返します。

 

●データ型

データ型

リテラル形式

Null

null

null

Boolean

true|false

例1:true

例2:false

DateTime

yyyy-mm-dd | yyyy-mm-ddThh:mm[:ss[.fffffff]]Z

例1:2000-01-01

例2:2000-01-01T12:00:00Z

Decimal

[0-9]+.[0-9]+M|m

2.345M

Double

[0-9]+ ((.[0-9]+) | [E[+ | -][0-9]+])d

例1:1E+10d

例2:2.029d

例3:2.0d

Single

[0-9]+.[0-9]+f

2.0f

Guid

[A-Fa-f0-9]

12345678-aaaa-bbbb-cccc-ddddeeeeffff

Int

[-][0-9]+

例1:16

例2:-16

String

'<任意のUTF-8文字>'

'ハローOData'