2013-05-16 28 views
8

WebApi'de OData'yı uygulamaya çalışıyorum. Halihazırda bulduğum tüm örneklerle tutarlı olan depo desenini ve EF5'i (arka planda) kullanıyorum. İşte işlerin nereye gittiği. Denetleyicide AutoMapper kullanılarak eşlenen modellerin arkasındaki EF oluşturulan sınıfları gizlemeye çalışıyorum. Gördüğüm örnekler repoWebApi ve Eşlenen Modellerle OData Uygulanması

'dan ne gelirse geri döner gibi görünüyor. Kontrolörde OData parametrelerini (eşlenmiş olan sonuçlara) uygulamak istemiyorum ama depodaki gecikmeli değeri korumak için yürütme. ODataCriteria'yı depoya aktarabilirim, ancak Appy'yi denediğimde bir hata alıyorum çünkü seçenekler/sonuçlar IQueryable < Model> IQueryable < EF_Class> sunum katmanından yazılıyor.

Ben ancak, yazının küçük bir parçasıydı ve yardımcı görünmüyordu, başkası başka bir yazı bu kadar atlatmış gördük.

Başkası bununla ilgilenmedi mi? EF sınıflarını gerçekten ifşa etmek istemiyorum. Oh, önce DB kullanıyorum. peşin

Teşekkür ...

cevap

0

İhtiyacınızı gösteren bazı kodlar.

( ToList() kullanarak) sorgu çalıştırıldıktan sağlamak için gerekli olan sonucu elde etmek için. Bunu yapmanın en etkili yolu, sayfalama (bonus) eklemek ve PageResult<> nesnesini döndürmektir.

public PageResult<WebPoco> Get(ODataQueryOptions<WebPoco> queryOptions) 
{ 
    var data2 = DatabaseData(); 

    //Create a set of ODataQueryOptions for the internal class 
    ODataModelBuilder modelBuilder = new ODataConventionModelBuilder(); 
    modelBuilder.EntitySet<DatabasePoco>("DatabasePoco"); 
    var context = new ODataQueryContext(
     modelBuilder.GetEdmModel(), typeof(DatabasePoco)); 
    var newOptions = new ODataQueryOptions<DatabasePoco>(context, Request); 

    var t = new ODataValidationSettings() { MaxTop = 25 }; 
    var s = new ODataQuerySettings() { PageSize = 25 }; 
    newOptions.Validate(t); 
    IEnumerable<DatabasePoco> results = 
     (IEnumerable<DatabasePoco>)newOptions.ApplyTo(data2, s); 

    int skip = newOptions.Skip == null ? 0 : newOptions.Skip.Value; 
    int take = newOptions.Top == null ? 25 : newOptions.Top.Value; 

    List<DatabasePoco> internalResults = results.Skip(skip).Take(take).ToList(); 

    // map from DatabasePoco to WebPoco here: 
    List<WebPoco> webResults; 

    PageResult<WebPoco> page = 
     new PageResult<WebPoco>(
      webResults, Request.GetNextPageLink(), Request.GetInlineCount()); 

    return page; 
} 

İşte o sevmediği,

private IQueryable<DatabasePoco> DatabaseData() 
{ 
    return (
     new DatabasePoco[] { 
      new DatabasePoco() { id = 1, name = "one", type = "a" }, 
      new DatabasePoco() { id = 2, name = "two", type = "b" }, 
      new DatabasePoco() { id = 3, name = "three", type = "c" }, 
      new DatabasePoco() { id = 4, name = "four", type = "d" }, 
      new DatabasePoco() { id = 5, name = "five", type = "e" }, 
      new DatabasePoco() { id = 6, name = "six", type = "f" }, 
      new DatabasePoco() { id = 7, name = "seven", type = "g" }, 
      new DatabasePoco() { id = 8, name = "eight", type = "h" }, 
      new DatabasePoco() { id = 9, name = "nine", type = "i" } 
     }) 
     .AsQueryable(); 
} 
+0

Bu yaklaşımı beğendim, maalesef, eski bir db ile çalışıyorum ve aşağıdaki hatayı alıyorum ... Karmaşık x tipi, Z işletmesi aracılığıyla Y türünü ifade eder. Bu konuda Google'da bir şey bulamıyorum. Sadece bir dairesel ref veya bir şey potansiyelini gösteren olduğunu varsayabilir ... – Lenny

+0

@Lenny - 'ToList()' db denkleminden kaldırmalıdır. Ama EF haritalarını bilen var mı ?! Proxy'ler, tembel yükleme vb. Ile ilgili herhangi bir şey olabilir. Hangi hat başarısız? – qujck

+0

onay bunun ardından teşekkürler http://stackoverflow.com/questions/15438195/odata-exception-the-complex-type-webtools-order-refers-to-the-entity-type-web ... – Lenny

0

iade Queryable yerine AutoMapper ait ({Id = x.Id} x => Yeni Model) mekanizması dbContext.dbSet.Select aracılığıyla ise. Daha sonra, Queryable üzerindeki koşulların uygulanması, EF LINQ sağlayıcısı tarafından otomatik olarak tercüme edilebilir ve değerlendirilebilir. Aksi takdirde, ifadeleri, Model özelliklerinden yola çıkarak, EF_ Sınıf özellikleri dışındaki ifadelere göre ifadeler olarak değiştiren özel bir LINQ sağlayıcısı yazmanız gerekecektir.

+1

Hmm test etmek için

using System.Web.Http; using System.Web.Http.OData; using System.Web.Http.OData.Builder; using System.Web.Http.OData.Query; 

test sınıfları

public class WebPoco { public int id { get; set; } public string name { get; set; } public string type { get; set; } } public class DatabasePoco { public int id { get; set; } public string name { get; set; } public string type { get; set; } } 

ve bazı veriler kullanılarak beyanlara

bu. EF sınıfını kullanırsam, id özelliğini (diğer kimliklerle birlikte) kaynağın uri'si olan gezinme özelliği lehine gizleyemem. Hala mümkün olabilmenin tek yolu, çirkin kısmi sınıf çalışması ya da EF sınıfını oluşturan t4 şablonunda yapılan değişiklikler olabilir. Bu yanlış mı gidiyorum? EF sınıflarını gerçekten paylaşmalı mıyım? – Lenny