Используйте денормализованные ссылки:
http://ravendb.net/faq/denormalized-references
по сути, у вас есть класс DenormalizedReference:
public class DenormalizedReference<T> where T : INamedDocument
{
public string Id { get; set; }
public string Name { get; set; }
public static implicit operator DenormalizedReference<T> (T doc)
{
return new DenormalizedReference<T>
{
Id = doc.Id,
Name = doc.Name
}
}
}
ваши документы выглядят так - я реализовал INamedDocumentинтерфейс - это может быть то, что вам нужно, хотя:
public class Company : INamedDocument
{
public string Name{get;set;}
public int Id { get; set; }
public IList<DenormalizedReference<Contact>> Contacts { get; set; }
public IList<DenormalizedReference<Task>> Tasks { get; set; }
}
public class Contact : INamedDocument
{
public string Name{get;set;}
public int Id { get; set; }
public DenormalizedReference<Company> Company { get; set; }
public IList<DenormalizedReference<Task>> Tasks { get; set; }
}
public class Task : INamedDocument
{
public string Name{get;set;}
public int Id { get; set; }
public DenormalizedReference<Company> Company { get; set; }
public DenormalizedReference<Contact> Contact { get; set; }
}
Теперь сохранение Задачи работает точно так же, как и раньше:
var task = new Task{
Company = myCompany,
Contact = myContact
};
Однако, потянув все это назад, вы будетеВы только собираетесь получить денормализованную ссылку на дочерние объекты.Для их гидратации я использую индекс:
public class Tasks_Hydrated : AbstractIndexCreationTask<Task>
{
public Tasks_Hydrated()
{
Map = docs => from doc in docs
select new
{
doc.Name
};
TransformResults = (db, docs) => from doc in docs
let Company = db.Load<Company>(doc.Company.Id)
let Contact = db.Load<Contact>(doc.Contact.Id)
select new
{
Contact,
Company,
doc.Id,
doc.Name
};
}
}
И используя ваш индекс для получения гидратированных задач:
var tasks = from c in _session.Query<Projections.Task, Tasks_Hydrated>()
where c.Name == "taskmaster"
select c;
Который я считаю довольно чистым:)
В качестве конструктивного разговора - общее правило состоит в том, что если вам когда-либо необходимо загрузить дочерние документы в одиночку как в - а не как часть родительского документа.Будь то для редактирования или просмотра - вы должны смоделировать его с его собственным идентификатором, как его собственный документ.Использование описанного выше метода делает это довольно простым.