2015-11-06 27 views
5

Aşağıdaki yöntemle çalışan (basitleştirilmiş) ODataController var.Nasıl Yapılır ODataQueryOptions

public class MyTypeController : ODataController 
{ 
    [HttpGet] 
    [EnableQuery] 
    [ODataRoute("myTypes")] 
    public IQueryable<MyType> GetMyTypes(ODataQueryOptions<MyType> options) 
    { 
    return _repo.myResultsAsQueryable(); 
    } 
} 
ben sunucudan bu yöntemi çağırmak için muktedir ve ben bir ODataQueryContext gerektiren bir ODataQueryOptions örneğini gerekir bunu yapmak istiyoruz

.

Bunun nasıl yapılacağına dair örnekler vardır (Örn. here ve here) ancak bunların tümü OData'nın önceki bir sürümüne başvuruyor gibi görünüyor. Şu anda ODataQueryContext yapıcısı, bulabildiğim herhangi bir örnekte ele alınmayan üçüncü bir bağımsız değişken (ODataPath yol) gerektirir.

Düzenleme: @snow_FFFFFF, Burada bazı bağlam var ... Ben sadece bir HttpClient aracılığıyla OData bitiş noktası tüketebilir ama dediğiniz gibi doğrudan IQueryable ile etkileşim istiyorum biliyoruz.

Sorun şu ki üzerinde çalıştığım uygulama, kullanıcıların başka kullanıcılar tarafından kaydedilip daha sonra geri çağrılabilen filtreler (gelişmiş arama motoru gibi) oluşturmasına olanak veriyor. Bir JS istemcisinden, süzgeci yalnızca kimliğe göre ararlar ve sorgu dizesine uygulanan süzgeçle OData bitiş noktasına karşı bir sorgu yayınlarlar. Bu, istemci tarafında çok iyi çalışır, ancak sunucu tarafında da benzer bir şey yapabilmeyi isterim.

Yapmak istediğim şey budur ancak ODataPath argümanını nasıl oluşturabilirim?

public IQueryable<MyType> FilterMyTypes(int filterID) 
{ 
    // lookup filter by filterID from db... 
    filter = "$filter=Status eq 1"; // for example... 

    ODataPath path = // but how can I get the path!!! 
    new ODataQueryContext(edmModel, typeof(MyType), path); 

    var uri = new HttpRequestMessage(HttpMethod.Get, "http://localhost:56339/mytypes?" + filter); 
    var opts = new ODataQueryOptions<MyType>(ctx, uri); 

    var results = new MyTypeController().GetMyTypes(opts); 
} 

Bunun başka uygulama olarak aşağıda dinamik gruplama desteklemek olacaktır:

[HttpGet] 
[Route("myTypes/{filterID:int}/groupby/{groupByFieldName}")] 
public IHttpActionResult GroupMyTypes(int filterID, string groupByFieldName) 
{ 
    // For example: get all Active MyTypes and group by AssignedToUserID... 

    // Get the results of the filter as IQueryable... 
    var results = FilterMyTypes(filterID); 

    // group on groupByFieldName 
    var grouped = results.GroupBy(x => GetPropertyValue(x,groupByFieldName)); 

    // select the groupByFieldName and the count 
    var transformedResults = grouped.Select(g => new { g.Key, Count = g.Count() }); 

    return Ok(transformedResults); 
} 
+1

http://github.com/OData/WebApi adresinde, başvurabileceğiniz birçok test vakası var. Örneğin, ODataQueryContext, bakın: https://github.com/OData/WebApi/blob/master/OData/test/UnitTest/System.Web.OData.Test/OData/Query/ODataQueryContextTests.cs#L181- L200 –

+0

Teşekkürler Sam, Bunu deneyeceğim .. Açık kaynak kodlu MS için kullanılmamış ... –

+0

Sam. Harikasın! Bunu bir cevaba koyarsan kabul edebilirim. Çok teşekkürler. Bir çekicilik gibi çalıştı. –

cevap

3

Tabi. ODataPath, OData Uri spec'u takip etmesi gereken ODataPathSegment (ler) in bir listesidir.

Web API OData yılında

, örneğin, bir ODataPath örneğini kolay:

~/entityset 

Daha:

IEdmModel model = GetEdmModel(); 
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet(setName); 
ODataPath path = new ODataPath(new EntitySetPathSegment(entitySet)); 

yukarıdaki path o kadar OData şablonu sahip olduğunu OData spec takip test durumları (kodlar) here

+1

1/25/2017'den itibaren Microsoft.AspNet.OData'nın en son kararlı sürümü v6.0.0'dır. Artık bir EntitySetPathSegment sınıfı yok gibi görünüyor. NuGet'te 5.9.1'e düşmem gerekiyordu. Aksi takdirde, ÇOK yardımcı soru ve ben gerçekten kaynak kod test vakaları için bağlantıyı takdir ettim. Bugün itibariyle – asporter

+0

borklu bağlantı. –

0

Kişisel OData kontrolör verilerinize bir HTTP arayüzü sağlayarak, görebilmek için HTTP üzerinden erişmek olmamalıdır (bile sunucudan)? Orada bir VS eklenti burada OData istemci kodu oluşturmak için:

https://visualstudiogallery.msdn.microsoft.com/9b786c0e-79d1-4a50-89a5-125e57475937

Veya, aynı proje neden olmasın dan denilebilir IQueryable döndüren bir ortak yöntem içinde böyle yapıyorsun eğer kodunuzu veya kontrol cihazından mı?

GÜNCELLEME: Orijinal söz konusu fazla bilgiye dayanarak: Bir denetleyici yönteminde tanımlanan ODataQueryOptions varsa

, size bu yöntemi aradığını iyi biçimli OData sorgu ayrıştırmak sağlayacaktır. Bunu, bir sonuç sorgusunun parçalarını çevirmek istediğimde kullanmıştım çünkü son sonucu döndürmek için birden fazla veri kaynağını sorguladım.

Odak dışı parametreleri ve seçenekleri alan bir şey istediğiniz gibi geliyor. Bunun için, muhtemelen özel Eylemler bakmak gerekir ve ya Fonksiyonlar (sadece veri döndürmek eğer, muhtemelen bir fonksiyonu):

http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/odata-actions-and-functions

GÜNCELLEME 2.: Ve daha ayrıntılı okuma sonra, sanırım Senin noktasını özledim - Cevabım yok, ama onunla oynayacağım. URL'nin kendisini (yalnızca sorgu seçeneklerini başlatmanın aksine) yeniden biçimlendiremez misiniz?

UPDATE # 3: Sanırım bir oda isteği almayı düşünerek onu kandırmak için zor bir zaman geçireceksiniz ... bu gerçekten bir oda isteği değil. Geri benim orijinal cevapta belirtildiği ikinci seçeneğe - neden oradan kullanabilir ve OData kontrolör kullanabileceği bir yaygın yöntem - böyle bir şey:

// some sort of helper class 
public class HelperObject 
{ 
    public static IQueryable<MyType> GetGroupedValues(int filterID, string groupByFieldName) 
    { 
     // all your code/logic here 
    } 
} 

// your odata controller uses the helper 
[HttpGet] 
[Route("myTypes/{filterID:int}/groupby/{groupByFieldName}")] 
public IHttpActionResult GroupMyTypes(int filterID, string groupByFieldName) 
{ 
    return Ok(HelperObject.GetGroupedValues(filterID, groupByFieldName)); 
} 

// ... and so does your other code that wants to do the same thing 
var x = HelperObject.GetGroupedValues(filterID, groupByFieldName);