Question

i m trying to convert a SQL LINQ query into RavenDB LINQ query but it says tha cannot user groupby in ravendb i have searched alot and find method named MAPREDUCE to use groupby in RavenDB but cant understand how to use it i know my question may be a duplicate question but cant find solution so i have to post it on SO here is my query

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() });

help me in converting that

Was it helpful?

Solution

Assuming your model looks something like this:

public class Calendar
{
    public string Id {get; set;}
    public DateTime Start {get; set;}
    public int Duration {get; set;}
}

First you would define a type for the results you are wanting:

public class CalendarResult
{
    public DateTime Date { get; set; }
    public int Count { get; set; }
}

Then you can build a map-reduce index like this:

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)
                   };
    }
}

Add that to your database like this:

documentStore.ExecuteIndex(new CalendarsByDate());

Or if you have many indexes in your app, you may prefer to scan for them like this instead:

IndexCreation.CreateIndexes(GetType().Assembly, documentStore);

Then finally, you can query the index like this:

var results = session.Query<CalendarResult, CalendarsByDate>()
                     .Where(x => x.Date >= fromDate && x.Date <= toDate);

You can read more about map-reduce indexes here and here. There is a detailed explanation of how they work internally here.

One thing to note - I did not involve the duration of each item in this logic like you did in the original query. If you really think through what you're doing here, you'll find that you weren't really using that anyway. The only place it would matter is if your calendar events could span multiple days, in which case you've got a lot more work to do in either the EF or Raven form.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top