如何在RavenDB中实现非规范化引用

时间:2012-05-08 09:56:24

标签: ravendb

我想在存储在RavenDB文档数据库中的两个实体之间有一个引用。由于这不是关系数据库,我知道我应该使用RavenDBs文档中描述的非规范化引用技术。虽然起初这看起来很好,但是一旦我开始创建包含双向引用的真实世界域“层次结构”,保持所有这些引用最新的努力感觉不成比例。我觉得我可能在某个地方出错了。

您能解释一下使用RavenDB建模一个相当复杂的域层次结构的最佳/最简单方法吗?

由于

1 个答案:

答案 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

就是这样。你知道,现在我全力以赴,我可以看到你的意思。 只是为了更新引用而做了很多工作。也许服务代码可以更加干燥并重用于不同的关系类型,但我没有看到如何摆脱编写大量索引,每个引用类型一个。