Thank you@stefaner We are not allowed to add any property (RavenId) to the main model. There are some other approaches to implement: - Use
Id.ToString() for RavenDB document - Develop internal classes to store/retrieve in RavenDB
For the first approach here is a simple example: public class RavenDbEntityRepository<TEntity> : IEntityRepository<TEntity> where TEntity : class, IEntity{ private readonly IAsyncDocumentSession _session; public RavenDbEntityRepository(IAsyncDocumentSession session) { _session = session; } public async Task<TEntity?> Create(TEntity entity, CancellationToken cancellationToken = default) { // Convert Guid to string for RavenDB document ID await _session.StoreAsync(entity, entity.Id.ToString(), cancellationToken); await _session.SaveChangesAsync(cancellationToken); return entity; } public async Task<IEnumerable<TEntity>> CreateMany(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default) { foreach (var entity in entities) { await _session.StoreAsync(entity, entity.Id.ToString(), cancellationToken); } await _session.SaveChangesAsync(cancellationToken); return entities; } public async Task<TEntity?> Update(TEntity entity, CancellationToken cancellationToken = default) { // In RavenDB, StoreAsync updates an entity if it already exists await _session.StoreAsync(entity, entity.Id.ToString(), cancellationToken); await _session.SaveChangesAsync(cancellationToken); return entity; } public async Task<TEntity?> Delete(Guid id, CancellationToken cancellationToken = default) { // Convert Guid to string for querying var entity = await _session.LoadAsync<TEntity>(id.ToString(), cancellationToken); if (entity != null) { _session.Delete(entity); await _session.SaveChangesAsync(cancellationToken); } return entity; } public async Task<IEnumerable<TEntity>> DeleteMany(IEnumerable<Guid> ids, CancellationToken cancellationToken = default) { var deletedEntities = new List<TEntity>(); foreach (var id in ids) { var entity = await _session.LoadAsync<TEntity>(id.ToString(), cancellationToken); if (entity != null) { _session.Delete(entity); deletedEntities.Add(entity); } } await _session.SaveChangesAsync(cancellationToken); return deletedEntities; } public async Task<IEnumerable<TEntity>> GetAll(CancellationToken cancellationToken = default) { return await _session.Query<TEntity>().ToListAsync(cancellationToken); } public async Task<TEntity?> GetById(Guid id, CancellationToken cancellationToken = default) { // Convert Guid to string for querying return await _session.LoadAsync<TEntity>(id.ToString(), cancellationToken); } public async Task<IEnumerable<TEntity>> GetByIds(IEnumerable<Guid> ids, CancellationToken cancellationToken = default) { // Convert Guid list to string list for querying var stringIds = ids.Select(id => id.ToString()); return await _session.LoadAsync<TEntity>(stringIds, cancellationToken); }}
For the second approach, for theApiToken entity, you may have the below class: public class RavenApiToken : ApiToken{ public string RavenId { get; set; } = default!;}
And map the the main model ApiKey before storing into the RavenDB model RavenApiToken (using AutoMapper, manual mapping, etc.) |
Hi,
I wrote a repository for RavenDB. Maybe not the most elegant, but it works. Any suggestions and/or corrections are welcome.
I needed to do some minor changes to the Entity class, but I don't think it will effect any of the other repositories.
It turns out that RavenDB doesn't like Guid as Id property. So I introduced a second property just for RavenDB. The system still use Id and Guid, l but RavenDB use RavenId as an internal identifier.