I am new to mongodb and I am working on mvc4 web application for a new project.
I want to use repository pattern that will talk to a mongodb context for database level communications.
Simple interface that I have used with Entity Framework 4.0 is following. The find members are the problematic area for me. I don't have a clue how to proceed with them with mongodb context.
public interface IRepository<T> where T : class
{
void Add(T entity);
void Remove(T entity);
IQueryable<T> Find(Expression<Func<T, bool>> predicate);
//IQueryable<T> FindAll();
}
I have a very simple model that is called Hero its drive from ImongoEntity which provides a member called accessId.
public class Hero : MongoDB.Kennedy.IMongoEntity
{
public ObjectId _id { get; set; }
public string Name { get; set; }
public string Alias { get; set; }
public string _accessId { get; set;}
}
Context class is very simple you can see the collection of Heros exposted as IQueryable property.
public class MongoDataConetext: MongoDB.Kennedy.ConcurrentDataContext
{
public MongoDataConetext(string databaseName, string serverName="localhost") : base(databaseName, serverName)
{
}
public IQueryable<Hero> Heros {
get {
return base.GetCollection<Hero>().AsQueryable();
}
}
}
Now in my repository most simple methods are add and remove they successfully talk to mongodb context and get entities added or deleted from mongodb. Find method however gives me compiler level errors. I need help for my find and find all method. I am using genrics because I need my repositry class for enties like hero, solution, project, user and category.
public class Repository<T> : IRepository<T> where T : class, IMongoEntity
{
private readonly MongoDataConetext _ctx;
public Repository(MongoDataConetext ctx)
{
_ctx = ctx;
}
public void Add(T entity)
{
_ctx.Save(entity);
}
public void Remove(T entity)
{
_ctx.Delete(entity);
}
public IQueryable<T> Find(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
_ctx.Heros.Where(predicate);
//throw new NotImplementedException();
}
//public IQueryable<T> FindAll()
//{
// throw new NotImplementedException();
//}
}
If you are interested in an implementation similar to Rob Connery's and NBlog storage code but using the mongodb csharp driver 2.0 (that is asynchronous), you can look at:
https://github.com/alexandre-spieser/mongodb-generic-repository
You can then write a custom repository inheriting from BaseMongoRepository.
public interface ITestRepository : IBaseMongoRepository
{
void DropTestCollection<TDocument>();
void DropTestCollection<TDocument>(string partitionKey);
}
public class TestRepository : BaseMongoRepository, ITestRepository
{
public TestRepository(string connectionString, string databaseName) : base(connectionString, databaseName)
{
}
public void DropTestCollection<TDocument>()
{
MongoDbContext.DropCollection<TDocument>();
}
public void DropTestCollection<TDocument>(string partitionKey)
{
MongoDbContext.DropCollection<TDocument>(partitionKey);
}
}
Update: It is now available as its own nuget package:
Install-Package MongoDbGenericRepository
It looks like you're trying to use LINQ against your collections. That's perfect. You can do this much easier if you just expose an IQueryable property rather than write a Find()
method.
Here's an example from you sample above:
public class HeroRepository : IRepository<Heros> where T : class, IMongoEntity
{
// ...
public IQueryable<Heros> Heros
{
get
{
return _ctx.GetCollection<Heros>().AsQueryable();
// Careful there, doing this from memory, may be a little off...
}
}
}
Of course, then when you consume this class, just do:
var r = new HeroRepository();
var heros = r.Heros.Where(r => r.SuperPowerLevel > 20);
Generic
public class MongoDatabase<T> : IDatabase<T> where T : class, new()
{
private static string connectionString = "connectionString";
private static IMongoClient server = new MongoClient(connectionString);
private string collectionName;
private IMongoDatabase db;
protected IMongoCollection<T> Collection
{
get
{
return db.GetCollection<T>(collectionName);
}
set
{
Collection = value;
}
}
public MongoDatabase(string collection)
{
collectionName = collection;
db = server.GetDatabase(MongoUrl.Create(connectionString).DatabaseName);
}
public IMongoQueryable<T> Query
{
get
{
return Collection.AsQueryable<T>();
}
set
{
Query = value;
}
}
public T GetOne(Expression<Func<T, bool>> expression)
{
return Collection.Find(expression).SingleOrDefault();
}
public T FindOneAndUpdate(Expression<Func<T, bool>> expression, UpdateDefinition<T> update, FindOneAndUpdateOptions<T> option)
{
return Collection.FindOneAndUpdate(expression, update, option);
}
public void UpdateOne(Expression<Func<T, bool>> expression, UpdateDefinition<T> update)
{
Collection.UpdateOne(expression, update);
}
public void DeleteOne(Expression<Func<T, bool>> expression)
{
Collection.DeleteOne(expression);
}
public void InsertMany(IEnumerable<T> items)
{
Collection.InsertMany(items);
}
public void InsertOne(T item)
{
Collection.InsertOne(item);
}
}
İnterface
public interface IDatabase<T> where T : class, new()
{
IMongoQueryable<T> Query { get; set; }
T GetOne(Expression<Func<T, bool>> expression);
T FindOneAndUpdate(Expression<Func<T, bool>> expression, UpdateDefinition<T> update, FindOneAndUpdateOptions<T> option);
void UpdateOne(Expression<Func<T, bool>> expression, UpdateDefinition<T> update);
void DeleteOne(Expression<Func<T, bool>> expression);
void InsertMany(IEnumerable<T> items);
void InsertOne(T item);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With