2013-04-05 35 views
1

我想創建一個類似的類和索引定義到該索引如下圖所示:在RavenDB指數從集合檢索特定類型的項目的總和

public class Foo 
{ 
    public string Tag { get; set; } 
    public List<Bar> Bars { get; set; } 
} 

public abstract class Bar 
{ 
    public int Weight { get; set; } 
} 

public class IronBar : Bar { } 

public class ChocolateBar : Bar { } 

public class TagSummary 
{ 
    public string Tag { get; set; } 
    public int Count { get; set; } 
    public int TotalChocolateBarWeight { get; set; } 
    public int TotalIronBarWeight { get; set; } 
} 

public class TagSummaryIndex : AbstractIndexCreationTask<Foo, TagSummary> 
{ 
    public TagSummaryIndex() 
    { 
     Map = foos => from f in foos 
         select new 
         { 
          Tag = f.Tag, 
          Count = 1, 
          TotalChocolateBarWeight = f.Bars.OfType<ChocolateBar>().Sum(x=> x.Weight), 
          TotalIronBarWeight = f.Bars.OfType<IronBar>().Sum(x=> x.Weight) 
         }; 

     Reduce = results => from r in results 
          group r by r.Tag into g 
          select new 
          { 
           Tag = g.Key, 
           Count = g.Sum(x => x.Count), 
           TotalChocolateBarWeight = g.Sum(x => x.TotalChocolateBarWeight), 
           TotalIronBarWeight = g.Sum(x => x.TotalIronBarWeight) 
          }; 
    } 
} 

然而,當我嘗試創建索引

IndexCreation.CreateIndexes(this.GetType().Assembly, _documentStore); 

它引發InvalidOperationException。如果我從Map中刪除.OfType<T>()部件,那麼一切都很好(但不是我想要的)。我試過使用Where(x => x is ChocolateBar)和各種其他類型的檢查選項,但無濟於事。

我該如何去實現這一目標?

感謝

回答

2

也許你可以做最簡單的事情是添加一些屬性類是預先計算的分類彙總。

public class Foo 
{ 
    public string Tag { get; set; } 
    public List<Bar> Bars { get; set; } 
    public int ChocolateBarsWeight 
    { 
     get 
     { 
      return Bars.OfType<ChocolateBar>().Sum(x => x.Weight); 
     } 
    } 
    public int IronBarsWeight 
    { 
     get 
     { 
      return Bars.OfType<IronBar>().Sum(x => x.Weight); 
     } 
    } 
} 

然後在你的索引圖使用這些值:

TotalChocolateBarWeight = f.ChocolateBarsWeight, 
TotalIronBarWeight = f.IronBarsWeight 

不過,我傾向於同意.OfType<T>()應該在這種情況下工作,它沒有。原因在於,類型信息在每個條中被序列化爲json中的$type值。每當您存儲抽象基類型或接口時,都會發生這種情況。例如:

{ 
    "Tag": "A", 
    "Bars": [ 
     { 
      "$type": "YourNameSpace.ChocolateBar, YourNameSpace", 
      "Weight": 10 
     }, 
     { 
      "$type": "YourNameSpace.IronBar, YourNameSpace", 
      "Weight": 1000 
     } 
    ] 
} 

烏鴉應該可以挑上這一點,並妥善處理.OfType<T>()。我會建議它的下一個主要版本。

+0

感謝馬特,是的,這對我來說是一個方便的功能。我會暫時預先計算它們。 – 2013-04-06 08:12:35