如何在RavenDB中实现非规范化引用
我希望在RavenDB文档数据库中存储两个实体之间的引用。由于这不是关系数据库,我知道我应该使用RavenDBs文档中描述的非规范化引用技术。虽然一开始这看起来不错,但一旦我开始创建一个包括双向引用的真实世界域“层次结构”,保持所有这些引用最新的努力就显得不成比例了。我觉得我可能在什么地方出错了 您能否解释一下使用RavenDB对相当复杂的域层次结构建模的最佳/最简单方法如何在RavenDB中实现非规范化引用,ravendb,Ravendb,我希望在RavenDB文档数据库中存储两个实体之间的引用。由于这不是关系数据库,我知道我应该使用RavenDBs文档中描述的非规范化引用技术。虽然一开始这看起来不错,但一旦我开始创建一个包括双向引用的真实世界域“层次结构”,保持所有这些引用最新的努力就显得不成比例了。我觉得我可能在什么地方出错了 您能否解释一下使用RavenDB对相当复杂的域层次结构建模的最佳/最简单方法 谢谢我不确定这是否足以回答您的问题,但以下是我如何在RavenDB中创建一个非规范化引用(这是从真实代码中提取的,为了清晰起
谢谢我不确定这是否足以回答您的问题,但以下是我如何在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
类中的UserReference
属性中的UserName
属性。要进行更改,我们必须首先从RavenDB中找到正确的评估
实例,为此我们需要一个索引
乌鸦指数
public class Assessment_ByUserId : AbstractIndexCreationTask<Assessment>
{
public Assessment_ByUserId()
{
Map = assessments => from assessment in assessments
select new
{
User_Id = assessment.User.Id
};
}
}
就是这样。你知道,现在我把一切都说出来了,我明白你的意思了。仅仅更新一个参考资料就需要做很多工作。也许服务代码可以变得更加枯燥,并可用于不同的关系类型,但我不知道如何避免编写大量索引,每个引用类型一个。太好了,感谢biofractal,我正在尝试一种更复杂的方法,这看起来很理想。这篇博文可能会帮助您做出决定:感谢dasheddot,这真的很有用,谢谢。这看起来很有趣。多映射/减少索引
public class Assessment_ByUserId : AbstractIndexCreationTask<Assessment>
{
public Assessment_ByUserId()
{
Map = assessments => from assessment in assessments
select new
{
User_Id = assessment.User.Id
};
}
}
public static void SetUserName(IDocumentSession db, string userId, string userName)
{
var user = db.Load<User>(userId);
user.UserName = userName;
db.Save(user);
UpdateDenormalizedReferences(db, user, userName);
}
private static void UpdateDenormalizedReferences(IDocumentSession db, User user, string userName)
{
db.Advanced.DatabaseCommands.UpdateByIndex(
RavenIndexes.IndexAssessmentByUserId,
GetQuery(user.Id),
GetUserNamePatch(userName),
allowStale: true);
}
private static IndexQuery GetQuery(string propertyValue, string propertyName = "User_Id")
{
return new IndexQuery {Query = string.Format("{0}:{1}", propertyName, propertyValue)};
}
private static PatchRequest[] GetUserNamePatch(string referenceValue, string referenceName = "User")
{
return new[]
{
new PatchRequest
{
Type = PatchCommandType.Modify,
Name = referenceName,
Nested = new[]
{
new PatchRequest
{
Type = PatchCommandType.Set,
Name = "UserName",
Value = referenceValue
}
}
}
};
}