【发布时间】:2011-08-13 14:08:39
【问题描述】:
在 RavenDB 中,我可以存储 Products 和 Categories 类型的对象,它们将自动位于不同的集合中。这很好。
但是,如果我有 2 种逻辑上完全不同类型的产品,但它们使用相同的类怎么办?或者,我可以拥有通用数量的不同类型的产品,而不是 2。那么是否可以告诉 Raven 将产品文档拆分为集合,比方说基于 Product 类上可用的字符串属性?
提前谢谢你。
编辑: 我已经创建并注册了以下 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' 是新 raven 集合的名称(实体类型的名称也保存为 EntityData 对象上的单独字段)。
我将如何查询我的对象?在执行查询之前,我找不到可以在运行时定义我的集合的位置。
我必须执行一些原始的 lucene 查询吗?或者我可以实现一个查询监听器吗?
编辑: 我找到了一种使用动态定义的集合来存储、查询和删除对象的方法,但我不确定这是不是正确的方法:
文档存储监听器:
(我使用上面定义的类)
解析索引名称的方法:
private string GetIndexName(string typeId)
{
return "dynamic/" + typeId;
}
存储/查询/删除:
// 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);
}
我觉得它有点脏,但这是在指定集合名称运行时存储/查询/删除的方式吗?还是我这样陷害自己?
【问题讨论】:
-
为什么会有不同类型的产品,但使用相同的类类型?他们看起来并没有那么不同。
-
就我而言,我正在开发一个通用框架,其中有一个名为 Entity 的类。在运行时,无需创建新的 C# 类和重新编译任何代码即可配置新的实体类型。我在定义其类型的实体上有一个属性。如果我可以告诉 raven DB 基于属性将文档拆分为单独的集合,而不是创建新类并重新编译代码,那么这个问题可以概括为一个通用问题。
标签: collections definition ravendb