我正试图将SQL
LINQ
查询转换为RavenDB
LINQ
查询,但它表示无法在ravendb中使用groupby我已经搜索了很多,找到了一个名为MAPREDUCE
的方法来在RavenDB
中使用groupby,但不明白如何使用它。我知道我的问题可能是一个重复的问题,但找不到解决方案,所以我不得不把它发布在SO
上这是我的查询
var rslt = Session.Query<Models.Calendar>()
.Where(s => s.Start >= fromDate && System.Data.Objects.EntityFunctions.AddMinutes(s.Start, s.Duration) <= toDate)
.GroupBy(s => System.Data.Objects.EntityFunctions.TruncateTime(s.Start))
.Select(x => new { DateTimeScheduled = x.Key, Count = x.Count() });
帮助我转换
假设您的模型看起来像这样:
public class Calendar
{
public string Id {get; set;}
public DateTime Start {get; set;}
public int Duration {get; set;}
}
首先,你要为你想要的结果定义一种类型:
public class CalendarResult
{
public DateTime Date { get; set; }
public int Count { get; set; }
}
然后你可以像这样构建一个地图缩减索引:
public class CalendarsByDate : AbstractIndexCreationTask<Calendar, CalendarResult>
{
public CalendarsByDate()
{
Map = calendars => from calendar in calendars
select new
{
calendar.Start.Date,
Count = 1
};
Reduce = results => from result in results
group result by result.Date
into g
select new
{
Date = g.Key,
Count = g.Sum(x => x.Count)
};
}
}
将其添加到您的数据库中,如下所示:
documentStore.ExecuteIndex(new CalendarsByDate());
或者,如果你的应用程序中有很多索引,你可能更喜欢这样扫描它们:
IndexCreation.CreateIndexes(GetType().Assembly, documentStore);
最后,您可以这样查询索引:
var results = session.Query<CalendarResult, CalendarsByDate>()
.Where(x => x.Date >= fromDate && x.Date <= toDate);
你可以在这里和这里阅读更多关于map reduce索引的信息。这里有关于他们内部工作方式的详细解释。
需要注意的一点是,我没有像在原始查询中那样将每个项目的持续时间包含在这个逻辑中。如果你真的仔细想想你在这里做什么,你会发现你并没有真正使用它。唯一重要的地方是你的日历事件是否可以跨越多天,在这种情况下,你有更多的工作要做,无论是EF还是Raven形式。