2013-04-05 40 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