更新:这里有一个更全面展示问题https://gist.github.com/pauldambra/5051550
的要点啊,更多更新......如果我将Mailing类的Id属性设为字符串,那么一切正常。我应该放弃整数ID吗?
我有2个模特
public class Mailing
{
public int Id { get; set; }
public string Sender { get; set; }
public string Subject { get; set; }
public DateTime Created { get; set; }
}
public class Recipient
{
public Recipient()
{
Status = RecipientStatus.Pending;
}
public RecipientStatus Status { get; set; }
public int MailingId { get; set; }
}
在我的主页上,我想抓住最后10封邮件。有他们的收件人数(最终有不同的状态收件人,但......)
我做了以下索引
public class MailingWithRecipientCount : AbstractMultiMapIndexCreationTask<MailingWithRecipientCount.Result>
{
public class Result
{
public int MailingId { get; set; }
public string MailingSubject { get; set; }
public string MailingSender { get; set; }
public int RecipientCount { get; set; }
}
public MailingWithRecipientCount()
{
AddMap<Mailing>(mailings => from mailing in mailings
select new
{
MailingId = mailing.Id,
MailingSender = mailing.Sender,
MailingSubject = mailing.Subject,
RecipientCount = 0
});
AddMap<Recipient>(recipients => from recipient in recipients
select new
{
recipient.MailingId,
MailingSender = (string) null,
MailingSubject = (string)null,
RecipientCount = 1
});
Reduce = results => from result in results
group result by result.MailingId
into g
select new
{
MailingId = g.Key,
MailingSender = g.Select(m => m.MailingSender)
.FirstOrDefault(m => m != null),
MailingSubject = g.Select(m => m.MailingSubject)
.FirstOrDefault(m => m != null),
RecipientCount = g.Sum(r => r.RecipientCount)
};
}
}
我使用
查询public ActionResult Index()
{
return View(RavenSession
.Query<RavenIndexes.MailingWithRecipientCount.Result, RavenIndexes.MailingWithRecipientCount>()
.OrderByDescending(m => m.MailingId)
.Take(10)
.ToList());
}
我得到了:
System.FormatException:System.FormatException:输入字符串不是 以正确的格式。在System.Number.StringToNumber(String str, NumberStyles选项,NumberBuffer&amp; number,NumberFormatInfo信息, Boolean parseDecimal)
任何帮助表示赞赏
答案 0 :(得分:4)
是的,整数ID很痛苦。这主要是因为Raven总是存储一个完整的字符串文档密钥,你必须考虑何时使用密钥或你自己的id并进行适当的翻译。减少时,还需要对齐int和string数据类型。
让测试通过的最低要求是:
// in the "mailings" map
MailingId = mailing.Id.ToString().Split('/')[1],
// in the reduce
MailingId = g.Key.ToString(),
但是 - 您可以通过将发件人和主题字符串排除在外,使索引变得更小并且表现更好。你可以把它们放入变换中。
这是一个简化的完整索引,可以做同样的事情。
public class MailingWithRecipientCount : AbstractIndexCreationTask<Recipient, MailingWithRecipientCount.Result>
{
public class Result
{
public int MailingId { get; set; }
public string MailingSubject { get; set; }
public string MailingSender { get; set; }
public int RecipientCount { get; set; }
}
public MailingWithRecipientCount()
{
Map = recipients => from recipient in recipients
select new
{
recipient.MailingId,
RecipientCount = 1
};
Reduce = results => from result in results
group result by result.MailingId
into g
select new
{
MailingId = g.Key,
RecipientCount = g.Sum(r => r.RecipientCount)
};
TransformResults = (database, results) =>
from result in results
let mailing = database.Load<Mailing>("mailings/" + result.MailingId)
select new
{
result.MailingId,
MailingSubject = mailing.Subject,
MailingSender = mailing.Sender,
result.RecipientCount
};
}
}
顺便说一下,你知道RavenDB.Tests.Helpers包吗?它提供了一个简单的基类RavenTestBase
,您可以继承它,为您完成大部分的工作。
using (var store = NewDocumentStore())
{
// now you have an initialized, in-memory, embedded document store.
}
此外 - 您可能不应在单元测试中扫描程序集中的索引。您可能会引入不属于您测试内容的索引。更好的方法是单独创建索引,如下所示:
documentStore.ExecuteIndex(new MailingWithRecipientCount());