В RavenDB я могу хранить объекты типа Продукты и Категории, и они будут автоматически размещаться в разных коллекциях. Это хорошо.
Но что, если у меня есть 2 совершенно разных типа продуктов, но они используют один и тот же класс? Или вместо 2 я мог бы иметь общее количество различных типов продуктов. Можно ли тогда сказать Raven разделить документы продукта на коллекции, скажем, на основе свойства строки, доступного в классе Product?
Спасибо заранее.
EDIT:
Я создал и зарегистрировал следующий StoreListener, который изменяет коллекцию для документов, которые будут храниться во время выполнения. Это приводит к тому, что документы правильно хранятся в разных коллекциях и, таким образом, создается правильная логическая группировка документов.
public class DynamicCollectionDefinerStoreListener : IDocumentStoreListener
{
public bool BeforeStore(string key, object entityInstance, RavenJObject metadata)
{
var entity = entityInstance as EntityData;
if(entity == null)
throw new Exception("Cannot handle object of type " + EntityInstance.GetType());
metadata["Raven-Entity-Name"] = RavenJToken.FromObject(entity.TypeId);
return true;
}
public void AfterStore(string key, object entityInstance, RavenJObject metadata)
{
}
}
Однако, похоже, мне тоже нужно скорректировать свои запросы, чтобы можно было вернуть объекты обратно. Мой типичный запрос раньше выглядел так:
session => session.Query<EntityData>().Where(e => e.TypeId == typeId)
При этом typeId - это имя новых коллекций воронов (и имя типа сущности, сохраняемое как отдельное поле в объекте EntityData).
Как мне поступить с просьбой вернуть мои объекты? Я не могу найти место, где я могу определить свою коллекцию во время выполнения до выполнения моего запроса.
Должен ли я выполнять некоторые необработанные запросы lucene? Или я могу реализовать прослушиватель запросов?
EDIT:
Я нашел способ хранения, запроса и удаления объектов с использованием динамически определенных коллекций, но я не уверен, что это правильный способ сделать это:
Слушатель хранилища документов:
(я использую класс, определенный выше)
Метод разрешения имен индексов:
private string GetIndexName(string typeId)
{
return "dynamic/" + typeId;
}
Магазин / Query / Удалить:
// Storing
session.Store(entity);
// Query
var someResults = session.Query<EntityData>(GetIndexName(entity.TypeId)).Where(e => e.EntityId == entity.EntityId)
var someMoreResults = session.Advanced.LuceneQuery<EntityData>(GetIndexName(entityTypeId)).Where("TypeId:Colors AND Range.Basic.ColorCode:Yellow)
// Deleting
var loadedEntity = session.Query<EntityData>(GetIndexName(entity.TypeId)).Where(e =>
e.EntityId == entity.EntityId).SingleOrDefault();
if (loadedEntity != null)
{
session.Delete<EntityData>(loadedEntity);
}
У меня такое ощущение, что он становится немного грязным, но это способ хранить / запрашивать / удалять при указании имен коллекций во время выполнения? Или я поймаю себя в ловушку таким образом?