Skip to content
This repository was archived by the owner on Feb 22, 2020. It is now read-only.

Added Support for 2.0 async driver #24

Open
wants to merge 2 commits into
base: v2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions MongoRepository/Repository/IRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

/// <summary>
/// IRepository definition.
Expand Down Expand Up @@ -45,42 +46,92 @@ public interface IRepository<T, TKey> : IQueryable<T>
/// <param name="entities">The entities of type T.</param>
void Add(IEnumerable<T> entities);

/// <summary>
/// Adds the new entity in the repository asynchronously.
/// </summary>
/// <param name="entity">The entity to add.</param>
/// <returns>The added entity including its new ObjectId.</returns>
Task<T> AddAsync(T entity);

/// <summary>
/// Adds the new entities in the repository asynchronously.
/// <param name="entities">The entities to add.</param>
/// </summary>
Task AddAsync(IEnumerable<T> entities);

/// <summary>
/// Upserts an entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns>The updated entity.</returns>
T Update(T entity);

/// <summary>
/// Upserts an entity asynchronously.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns>The updated entity.</returns>
Task<T> UpdateAsync(T entity);

/// <summary>
/// Upserts the entities.
/// </summary>
/// <param name="entities">The entities to update.</param>
void Update(IEnumerable<T> entities);

/// <summary>
/// Upserts the entities asynchronously.
/// </summary>
/// <param name="entities">The entities to update.</param>
Task UpdateAsync(IEnumerable<T> entities);


/// <summary>
/// Deletes an entity from the repository by its id.
/// </summary>
/// <param name="id">The entity's id.</param>
void Delete(TKey id);

/// <summary>
/// Deletes an entity from the repository by its ObjectId asynchronously.
/// </summary>
/// <param name="id">The ObjectId of the entity.</param>
void DeleteAsync(TKey id);

/// <summary>
/// Deletes the given entity.
/// </summary>
/// <param name="entity">The entity to delete.</param>
void Delete(T entity);

/// <summary>
/// Deletes the given entity asynchronously.
/// </summary>
/// <param name="entity">The entity to delete.</param>
Task DeleteAsync(T entity);

/// <summary>
/// Deletes the entities matching the predicate.
/// </summary>
/// <param name="predicate">The expression.</param>
void Delete(Expression<Func<T, bool>> predicate);

/// <summary>
/// Deletes the entities matching the predicate asynchronously.
/// </summary>
/// <param name="predicate">The expression.</param>
Task DeleteAsync(Expression<Func<T, bool>> predicate);

/// <summary>
/// Deletes all entities in the repository.
/// </summary>
void DeleteAll();

/// <summary>
/// Deletes all entities in the repository asynchronously.
/// </summary>
void DeleteAllAsync();

/// <summary>
/// Counts the total entities in the repository.
/// </summary>
Expand Down
87 changes: 87 additions & 0 deletions MongoRepository/Repository/MongoRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

/// <summary>
/// Deals with entities in MongoDb.
Expand Down Expand Up @@ -131,6 +132,26 @@ public virtual void Add(IEnumerable<T> entities)
this.collection.InsertMany(entities);
}

/// <summary>
/// Adds the new entity in the repository asynchronously.
/// </summary>
/// <param name="entity">The entity T.</param>
/// <returns>The added entity including its new ObjectId.</returns>
public virtual async Task<T> AddAsync(T entity)
{
await this.collection.InsertOneAsync(entity);
return entity;
}

/// <summary>
/// Adds the new entities in the repository asynchronously.
/// </summary>
/// <param name="entities">The entities of type T.</param>
public virtual async Task AddAsync(IEnumerable<T> entities)
{
await this.collection.InsertManyAsync(entities);
}

/// <summary>
/// Upserts an entity.
/// </summary>
Expand All @@ -145,6 +166,21 @@ public virtual T Update(T entity)
return entity;
}

/// <summary>
/// Upserts an entity asynchronously.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns>The updated entity.</returns>
public virtual async Task<T> UpdateAsync(T entity)
{
if (entity.Id == null)
await this.AddAsync(entity);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't possible to use UpdateOneAsync here and sending Update options upsert = true. I've not looked into the new API but can't we build UpdateDefintion from entity (which means update everything) as default?

else
await this.collection.ReplaceOneAsync(GetIDFilter(entity.Id), entity, new UpdateOptions { IsUpsert = true });
return entity;

}

/// <summary>
/// Upserts the entities.
/// </summary>
Expand All @@ -155,6 +191,20 @@ public virtual void Update(IEnumerable<T> entities)
this.collection.ReplaceOne(GetIDFilter(entity.Id), entity, new UpdateOptions { IsUpsert = true });
}



/// <summary>
/// Upserts the entities asynchronously
/// </summary>
/// <param name="entities">The entities to update</param>
public virtual async Task UpdateAsync(IEnumerable<T> entities)
{
foreach (T entity in entities)
await this.collection.ReplaceOneAsync(GetIDFilter(entity.Id), entity, new UpdateOptions { IsUpsert = true });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here instead of calling ReplaceOne can't we directly call UpdateManyAsync which will make it a batch opration instead of calling ReplaceOne on every entity??

}



/// <summary>
/// Deletes an entity from the repository by its id.
/// </summary>
Expand All @@ -164,6 +214,16 @@ public virtual void Delete(TKey id)
this.collection.DeleteOne(GetIDFilter(id));
}

/// <summary>
/// Deletes an entity from the repository by its ObjectId asynchronously.
/// </summary>
/// <param name="id">The ObjectId of the entity.</param>
public virtual void DeleteAsync(TKey id)
{
var filter = Builders<T>.Filter.Where(x => x.Id.Equals(id));
this.collection.DeleteOneAsync(filter);
}

/// <summary>
/// Deletes an entity from the repository by its ObjectId.
/// </summary>
Expand All @@ -182,6 +242,15 @@ public virtual void Delete(T entity)
this.Delete(entity.Id);
}

/// <summary>
/// Deletes the given entity asynchronously.
/// </summary>
/// <param name="entity">The entity to delete.</param>
public virtual async Task DeleteAsync(T entity)
{
await DeleteAsync(x => x.Id.Equals(entity.Id));
}

/// <summary>
/// Deletes the entities matching the predicate.
/// </summary>
Expand All @@ -191,6 +260,16 @@ public virtual void Delete(Expression<Func<T, bool>> predicate)
this.collection.DeleteMany<T>(predicate);
}

/// <summary>
/// Deletes the entities matching the predicate asynchronously.
/// </summary>
/// <param name="predicate">The expression.</param>
public virtual async Task DeleteAsync(Expression<Func<T, bool>> predicate)
{
var filter = Builders<T>.Filter.Where(predicate);
await this.collection.DeleteManyAsync(filter);
}

/// <summary>
/// Deletes all entities in the repository.
/// </summary>
Expand All @@ -199,6 +278,14 @@ public virtual void DeleteAll()
this.collection.DeleteMany<T>(t => true);
}

/// <summary>
/// Deletes all entities in the repository asynchronously.
/// </summary>
public virtual async void DeleteAllAsync()
{
await this.collection.DeleteManyAsync(x => true);
}

/// <summary>
/// Counts the total entities in the repository.
/// </summary>
Expand Down
50 changes: 50 additions & 0 deletions MongoRepositoryTests/RepoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,56 @@ public void AddAndUpdateTest()
Assert.IsTrue(_customerRepo.Exists(c => c.HomeAddress.Country == "Alaska"));
}

[TestMethod]
public void AddAndUpdateAsyncTest()
{
IRepository<Customer> _customerRepo = new MongoRepository<Customer>();
IRepositoryManager<Customer> _customerMan = new MongoRepositoryManager<Customer>();

Assert.IsFalse(_customerMan.Exists);

var customer = new Customer();
customer.FirstName = "BobAsync";
customer.LastName = "Dillon";
customer.Phone = "0900999899";
customer.Email = "[email protected]";
customer.HomeAddress = new Address
{
Address1 = "North kingdom 15 west",
Address2 = "1 north way",
PostCode = "40990",
City = "George Town",
Country = "Alaska"
};

_customerRepo.AddAsync(customer).Wait();

Assert.IsTrue(_customerMan.Exists);

Assert.IsNotNull(customer.Id);

// fetch it back
var alreadyAddedCustomer = _customerRepo.Where(c => c.FirstName == "BobAsync").Single();

Assert.IsNotNull(alreadyAddedCustomer);
Assert.AreEqual(customer.FirstName, alreadyAddedCustomer.FirstName);
Assert.AreEqual(customer.HomeAddress.Address1, alreadyAddedCustomer.HomeAddress.Address1);

alreadyAddedCustomer.Phone = "10110111";
alreadyAddedCustomer.Email = "[email protected]";

_customerRepo.UpdateAsync(alreadyAddedCustomer).Wait();

// fetch by id now
var updatedCustomer = _customerRepo.GetById(customer.Id);

Assert.IsNotNull(updatedCustomer);
Assert.AreEqual(alreadyAddedCustomer.Phone, updatedCustomer.Phone);
Assert.AreEqual(alreadyAddedCustomer.Email, updatedCustomer.Email);

Assert.IsTrue(_customerRepo.Exists(c => c.HomeAddress.Country == "Alaska"));
}

[TestMethod]
public void ComplexEntityTest()
{
Expand Down