Je ne suis pas sûr que cela va assez aller loin pour répondre à votre question, mais voici comment je vais sur la création d'un dénormalisées de référence dans RavenDB (cela est pris à partir du code réel non essentiels supprimés pour plus de clarté)
domaine
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; }
}
Vous pouvez voir que j'ai une classe Assessment
qui fait référence à un User
. Cette référence utilisateur est gérée à l'aide de la classe UserReference
ci-dessous.
dénormalisées Référence
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
};
}
}
Notez comment la classe de référence porte également le UserName
. Cette valeur ne changera pas très souvent mais elle peut changer, nous avons donc besoin d'un moyen de mettre à jour la propriété UserName
dans la propriété UserReference
de la classe Assessment
. Pour faire la modification, nous devons d'abord trouver les bonnes instances de RavenDB et pour cela nous avons besoin d'un index.
Raven Index
public class Assessment_ByUserId : AbstractIndexCreationTask<Assessment>
{
public Assessment_ByUserId()
{
Map = assessments => from assessment in assessments
select new
{
User_Id = assessment.User.Id
};
}
}
Cet indice doit être invoqué chaque fois qu'une valeur de UserName
User
est mis à jour. J'ai une classe UserService
qui m'aide à coordonner toutes mes fonctions liées à l'utilisateur, donc c'est là que j'ai mis ce code.
Je réutilise ce code pour d'autres références afin qu'il ait été extrait un peu. Cela peut vous aider à créer les hiérarchies les plus complexes (ou peut-être que le «graphique de domaine» est une meilleure description) que vous voulez.
UserService
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
}
}
}
};
}
Ce qu'il est. Et vous savez, maintenant que je dépose tout cela, je peux voir ce que vous voulez dire. Il est beaucoup de travail juste pour mettre à jour une référence. Peut-être que le code de service peut être rendu plus SEC et réutilisé pour différents types de relations, mais je ne vois pas comment éviter d'écrire beaucoup d'index, un par type référencé.
Ce blog peut vous aider à décider: http://daniellang.net/how-to-handle-relations-in-ravendb/ – dasheddot
Merci dasheddot, c'est vraiment utile, merci. –
Cela semble intéressant. Cartes multiples/Réduire les index [ici] (http: // ayende.com/blog/89089/ravendb-multi-cartes-réduisent-index) – biofractal