2012-03-27 49 views
5

考慮以下類:最簡單的方式來拉平文檔視圖中RavenDB

public class Lookup 
{ 
    public string Code { get; set; } 
    public string Name { get; set; } 
} 

public class DocA 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public Lookup Currency { get; set; } 
} 

public class ViewA // Simply a flattened version of the doc 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public string CurrencyName { get; set; } // View just gets the name of the currency 
} 

我可以創建一個允許客戶端查詢視圖如下指標:

public class A_View : AbstractIndexCreationTask<DocA, ViewA> 
{ 
    public A_View() 
    { 
     Map = docs => from doc in docs 
         select new ViewA 
         { 
          Id = doc.Id, 
          Name = doc.Name, 
          CurrencyName = doc.Currency.Name 
         }; 

     Reduce = results => from result in results 
         group on new ViewA 
         { 
          Id = result.Id, 
          Name = result.Name, 
          CurrencyName = result.CurrencyName 
         } into g 
         select new ViewA 
         { 
          Id = g.Key.Id, 
          Name = g.Key.Name, 
          CurrencyName = g.Key.CurrencyName 
         }; 
    } 
} 

這肯定工程並將數據轉換爲客戶端應用程序所需的結構,從而生成所需的視圖結果。然而,這是不可行的冗長的,將是一個維護噩夢,並可能是相當低效的所有冗餘對象的建設。

是否有一種更簡單的方式創建一個具有所需結構(ViewA)的索引給定文檔集合(DocA)?

更多信息請 問題似乎是爲了有指數保持在轉化結構(ViewA)的數據,我們做了減少。看來,一個減少必須同時具有GROUP ON以及選擇以工​​作爲預期的那麼以下是無效的:

無效REDUCE條款1:

 Reduce = results => from result in results 
         group on new ViewA 
         { 
          Id = result.Id, 
          Name = result.Name, 
          CurrencyName = result.CurrencyName 
         } into g 
         select g.Key; 

這將產生:系統。 InvalidOperationException:變量初始值設定項選擇必須有一個帶有對象的lambda表達式創建表達式

顯然,我們需要「選擇新的」。

INVALID REDUCE第2項目:

 Reduce = results => from result in results 
         select new ViewA 
         { 
          Id = result.Id, 
          Name = result.Name, 
          CurrencyName = result.CurrencyName 
         }; 

這prduces:System.InvalidCastException:無法投類型 'ICSharpCode.NRefactory.Ast.IdentifierExpression' 的目的爲類型「ICSharpCode.NRefactory.Ast.InvocationExpression 」。顯然,我們還需要有'新組'。

感謝您提供任何幫助。

(注:從構造函數調用刪除類型(ViewA)對上述無效)

與正確的做法UPDATE

正如在回答下面所提到的,在這裏丹尼爾的博客概述就是在這個例子中做到這一點的正確方法:

public class A_View : AbstractIndexCreationTask<DocA, ViewA> 
{ 
    public A_View() 
    { 
     Map = docs => from doc in docs 
         select new ViewA 
         { 
          Id = doc.Id, 
          Name = doc.Name, 
          CurrencyName = doc.Currency.Name 
         }; 

     // Top-level properties on ViewA that match those on DocA 
     // do not need to be stored in the index. 
     Store(x => x.CurrencyName, FieldStorage.Yes); 
    } 
} 
+0

謝謝@Phill。我不知道在這裏發生的其他答案發生了什麼...... – 2012-11-01 22:49:42

回答

4

一個解決方案,在地圖只需壓平,並配置指標只存儲不存在DOCA性能。

public class A_View : AbstractIndexCreationTask<DocA, ViewA> 
{ 
    public A_View() 
    { 
     Map = docs => from doc in docs 
         select new ViewA 
         { 
          Id = doc.Id, 
          Name = doc.Name, 
          CurrencyName = doc.Currency.Name 
         }; 

     // Top-level properties on ViewA that match those on DocA 
     // do not need to be stored in the index. 
     Store(x => x.CurrencyName, FieldStorage.Yes); 
    } 
} 
+0

只是我注意到了一段時間我正在尋找的東西;如果您想使用索引來查詢,然後獲取您要查詢的原始實體,可以這樣做: 'DocumentSession.Query ()。其中​​(x => x.CurrencyName == 「歐元」)。由於()。First();' [Found here](http://ayende.com/blog/152833/orders-search-in-ravendb) – 2013-07-11 12:49:16

相關問題