2014-01-09 96 views
-1

獲得最終投射我真的不知道該怎麼表達我想要實現沒有呈現出一些僞代碼的效果 - 被定義從包裹的IQueryable

假設下面的DTO:

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public int Age { get; set; } 
} 

我們有2個不同的自定義IQueryable<T>類中定義:

public class InnerQueryable<T> : IQueryable<T> 
{ 
    // ... 
} 

public class OuterQueryable<T> : IQueryable<T> 
{ 
    public OuterQueryable(IQueryable<T> inner) 
    { 
     // Assign `inner` to a local variable to be used in `IQueryable<T>` impl. 
     // ... 
    } 

    // ... 
} 

注:OuterQueryable<T>在設計上延續了BEHA vior的任何其他IQueryable<T>類型通過包裝它。

,也可以簡單地創建一個相當幼稚擴展方法,以允許OuterQueryable<T>實現:

public static IQueryable<T> ToOuterQueryable<T>(this IQueryable<T> inner /*, ... */) 
{ 
    // Assume `OuterQueryable<T>` has a constructor that takes another `IQueryable<T>`. 
    return new OuterQueryable<T>(inner /*, ... */); 
} 

鑑於如下所示的表達式,是否有任何方式爲InnerQueryable<T>實例,以找出哪些特定的屬性被選擇一旦查詢被OuterQueryable<T>包裝?

InnerQueryContext.AsQueryable<Person>().Where(p => p.Age > 30) 
    .ToOuterQueryable().Select(p => new 
    { 
     p.FirstName, 
     p.LastName 
    }; 

反正爲InnerQueryable<T>知道查詢建 OuterQueryable<T>只返回Person.FirstNamePerson.LastName

如果它有助於顯示上下文,我有一個WCF數據服務返回我們的內部實體,但我需要能夠知道從服務返回內部實體的哪些特定成員。 WCF DS在這種情況下定義了OuterContext<T>,我還沒有找到攔截響應後投影的方法來告訴我我在找什麼。

任何想法都會受到歡迎。


UPDATE:什麼是InnerQueryable<T>OuterQueryable<T>

這個問題的答案是相當複雜的,如果你不熟悉WCF數據服務的架構,但這裏有雲:

在WCF數據服務,一個服務公開IQueryable<T>性質的DataServiceProvider實現(即EntityFrameworkDataServiceProvider,ReflectionDataServiceProvider或實現必要接口的自定義DataServiceProvider實現)。

這些核心IQueryable<T>屬性充當通過服務公開的資源的基礎,並建立在使用LINQ查詢的可組合性質的基礎上。使用上述Person實體一個簡單的例子看起來像:

public class SimpleContext 
{ 
    public IQueryable<Person> People 
    { 
     get 
     { 
      return new[] { 
       new Person { FirstName = "George", LastName = "Jetson", Age = 43 }, 
       new Person { FirstName = "Elroy", LastName = "Jetson", Age = 7 } 
      }.AsQueryable(); 
     } 
    } 
} 

SimpleContext然後將通過一個簡單的數據服務實施中引用:

public class SimpleDataService : DataService<SimpleContext> 
{ 
    // InitializeService method and others... 
} 

現在,當我查詢通過投影數據服務:

http://localhost/SimpleDataService/People()?$select=FirstName,LastName 

該框架將採取IQueryable<Person>SimpleDataContext.People和PAS返回通過內部的IQueryProvider/IQueryable實現,該實現瞭解如何從查詢字符串參數生成表達式樹,然後使用IQueryable<Person>作爲源來編寫另一個查詢。

從概念上講,我上面的原始問題描述瞭如何複製行爲,而不必擔心所有的WCF數據服務的東西。

+1

@MarcinJuraszek - 你是對的,InnerQueryable不能也不會知道它是什麼時候或是否被包裝。如果你願意的話,這是一個轉折點。 –

+0

什麼是**內部查詢**用於? –

+0

我認爲這會有所幫助,如果你解釋究竟是什麼'OuterQueryable'是什麼,它的目的是什麼。 – svick

回答

2

我還是不太明白爲什麼WCF DS需要OuterQueryable。它需要做的是解析查詢,然後在此基礎上調用InnerQueryable

如果您的InnerQueryable確實有某種包裝,那麼完全由包裝來決定您的包裝可查詢將能夠看到什麼。如果包裝器只是將每個方法調用轉發給包裝對象,那麼您將能夠直接看到所有東西。另一方面,如果包裝完全沒有做任何事情,那麼你根本無法觀察任何東西。

+0

雖然我同意它可能不是最好的設計,但這是我遇到過的一種模式在社區和框架內找到了一點代碼。外層的'IQueryable'包裝實際上確實做了很多工作來隱藏WCF DS內部行爲的細節,但是當嘗試執行任何取決於它的操作的操作時,這同樣是一種詛咒。我會繼續研究代碼,並讓其他人可以提供洞察力,希望這不是完全沒有希望的。謝謝回答。 +1的洞察力。 –