Skip to content

Instantly share code, notes, and snippets.

@brunomlopes
Created May 7, 2012 02:55
Show Gist options
  • Save brunomlopes/2625592 to your computer and use it in GitHub Desktop.
Save brunomlopes/2625592 to your computer and use it in GitHub Desktop.
Strange RavenDB behaviour with counts
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Raven.Client;
using Raven.Client.Embedded;
using Raven.Client.Indexes;
namespace ConsoleApplication5
{
class Program
{
static void Main()
{
var store = new EmbeddableDocumentStore {RunInMemory = true}.Initialize();
IndexCreation.CreateIndexes(typeof(Program).Assembly, store);
var userA = new Person
{
Id = "person/1", Name = "User A"
};
var userB = new Person
{
Id = "person/2", Name = "User B"
};
using(var session = store.OpenSession())
{
session.Store(userA);
session.Store(userB);
session.Store(new Project
{
Name = "Proj A",
Activities = new List<Activity>
{
new Activity
{
Name = "Activity A",
Tasks = new List<Task>
{
new Task
{
Name = "Task A",
Owner = userA
},
new Task
{
Name = "Task B",
Owner = userA
},
}
},
new Activity
{
Name = "Activity B",
Tasks = new List<Task>
{
new Task
{
Name = "Task C",
Owner = userA
},
new Task
{
Name = "Task D for userB",
Owner = userB
},
}
},
}
});
session.SaveChanges();
}
int tasksForUserA = 3;
int tasksForUserB = 1;
using(var session = store.OpenSession())
{
var result = session.Query<TasksCount_ForPerson.Result, TasksCount_ForPerson>().Customize(c => c.WaitForNonStaleResults()).ToList();
Debug.Assert(tasksForUserA == result.Single(s => s.Owner.Id == userA.Id).Count);
Debug.Assert(tasksForUserB == result.Single(s => s.Owner.Id == userB.Id).Count);
}
using (var session = store.OpenSession())
{
var project = session.Query<Project>().First();
// I only change the name of the tasks, which should not cause the counts to go up
project.Activities.ElementAt(0).Tasks.ElementAt(0).Name = "Touch task";
project.Activities.ElementAt(0).Tasks.ElementAt(1).Name = "Touch task 2";
project.Activities.ElementAt(1).Tasks.ElementAt(0).Name = "Touch Task 3";
project.Activities.ElementAt(1).Tasks.ElementAt(1).Name = "Touch task 4";
session.SaveChanges();
}
using (var session = store.OpenSession())
{
var result = session.Query<TasksCount_ForPerson.Result, TasksCount_ForPerson>().Customize(c => c.WaitForNonStaleResults()).ToList();
// these two will fail.
Debug.Assert(tasksForUserA == result.Single(s => s.Owner.Id == userA.Id).Count);
Debug.Assert(tasksForUserB == result.Single(s => s.Owner.Id == userB.Id).Count);
}
}
}
public class TasksCount_ForPerson : AbstractIndexCreationTask<Project, TasksCount_ForPerson.Result>
{
public class Result
{
public Person Owner { get; set; }
public int Count { get; set; }
}
public TasksCount_ForPerson()
{
Map = projects =>
projects
.SelectMany(p => p.Activities)
.SelectMany(a => a.Tasks)
.Select(task =>
new
{
task.Owner,
Count = 1
}
);
Reduce =
results => results
.GroupBy(g => g.Owner.Id)
.Select(p => new
{
Owner = p.Select(r => r.Owner).First(),
Count = p.Sum(result => result.Count)
});
}
}
public class Project
{
public string Id { get; set; }
public string Name { get; set; }
public IList<Activity> Activities { get; set; }
public Project()
{
Activities = new List<Activity>();
}
}
public class Activity
{
public string Name { get; set; }
public Person Owner { get; set; }
public IList<Task> Tasks { get; set; }
public Activity()
{
Tasks = new List<Task>();
}
}
public class Task
{
public string Name { get; set; }
public Person Owner { get; set; }
public bool Done { get; set; }
}
public class Person
{
public string Id { get; set; }
public string Name { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment