我想在存储在RavenDB文档数据库中的两个实体之间有一个引用。由于这不是关系数据库,我知道我应该使用RavenDBs文档中描述的非规范化引用技术。虽然起初这看起来很好,但是一旦我开始创建包含双向引用的真实世界域“层次结构”,保持所有这些引用最新的努力感觉不成比例。我觉得我可能在某个地方出错了。
您能解释一下使用RavenDB建模一个相当复杂的域层次结构的最佳/最简单方法吗?
由于
答案 0 :(得分:6)
我不确定这是否足以回答你的问题,但这里是我如何在RavenDB中创建一个非规范化引用(这是从真实代码中删除,为了清晰起见,删除了非必需品)
<强>域强>
public class User : IUserIdentity
{
public string UserName { get; set; }
public IEnumerable<string> Claims { get; set; }
public string Id { get; set; }
public Guid FormsAuthenticationGuid { get; set; }
}
public class Assessment
{
public string Id { get; set; }
public UserReference User { get; set; }
public AssessmentState State { get; set; }
}
您可以看到我有一个引用Assessment
的{{1}}类。此用户参考使用下面的User
类进行管理。
非规范化参考
UserReference
请注意引用类如何带有public class UserReference
{
public string Id { get; set; }
public string UserName { get; set; }
public static implicit operator UserReference(User user)
{
return new UserReference
{
Id = user.Id,
UserName = user.UserName
};
}
}
。此值不会经常更改,但可能会更改,因此我们需要一种方法来更新UserName
类中保存的UserName
属性中的UserReference
属性。要进行更改,我们必须首先从RavenDB中找到正确的Assessment
实例,为此我们需要一个索引。
乌鸦指数
Assessment
只要更新public class Assessment_ByUserId : AbstractIndexCreationTask<Assessment>
{
public Assessment_ByUserId()
{
Map = assessments => from assessment in assessments
select new
{
User_Id = assessment.User.Id
};
}
}
的{{1}}值,就需要调用此索引。我有一个User
类,可以帮助我协调所有与用户相关的功能,这就是我放置此代码的地方。
我将此代码重用于其他引用,因此它已经被抽象出来了。这可以帮助您创建更复杂的层次结构(或者可能是“域图”是更好的描述)。
<强> UserService 强>
UserName
就是这样。你知道,现在我全力以赴,我可以看到你的意思。 只是为了更新引用而做了很多工作。也许服务代码可以更加干燥并重用于不同的关系类型,但我没有看到如何摆脱编写大量索引,每个引用类型一个。