-
-
Save antdimot/5037532 to your computer and use it in GitHub Desktop.
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using System.Text; | |
using System.Threading.Tasks; | |
using MongoDB.Bson; | |
using MongoDB.Driver; | |
using MongoDB.Driver.Builders; | |
using MongoDB.Driver.Linq; | |
namespace PRJ.Data | |
{ | |
public class Repository<T> where T : IEntity<ObjectId> | |
{ | |
DataContext _context; | |
MongoCollection<T> _collection; | |
public MongoCollection<T> Collection { get { return _collection; } } | |
public Repository( DataContext context ) | |
{ | |
_context = context; | |
_collection = _context.GetDatabase().GetCollection<T>( typeof( T ).Name.ToLower() ); | |
} | |
private IQueryable<T> CreateSet() | |
{ | |
return _collection.AsQueryable<T>(); | |
} | |
public T Insert( T instance ) | |
{ | |
try | |
{ | |
instance.Id = ObjectId.GenerateNewId(); | |
_collection.Insert<T>( instance ); | |
return instance; | |
} | |
catch( Exception ex ) | |
{ | |
//todo: handle exception | |
throw ex; | |
} | |
} | |
public void Update( T instance ) | |
{ | |
try | |
{ | |
var query = Query<T>.EQ( o => o.Id, instance.Id ); | |
var update = Update<T>.Replace( instance ); | |
_collection.Update( query, update ); | |
} | |
catch( Exception ex ) | |
{ | |
//todo: handle exception | |
throw ex; | |
} | |
} | |
public void Delete( ObjectId id, bool logical = true ) | |
{ | |
try | |
{ | |
if( logical ) | |
{ | |
_collection.Update( | |
Query<T>.EQ<ObjectId>( p => p.Id, id ), | |
Update<T>.Set<bool>( p => p.Deleted, true ) ); | |
} | |
else | |
{ | |
_collection.Remove( Query<T>.EQ<ObjectId>( p => p.Id, id ) ); | |
} | |
} | |
catch( Exception ex ) | |
{ | |
//todo: handle exception | |
throw ex; | |
} | |
} | |
public T GetById( ObjectId id ) | |
{ | |
return this.Single( o => o.Id == id ); | |
} | |
public T Single( Expression<Func<T, bool>> predicate = null ) | |
{ | |
var set = CreateSet(); | |
var query = ( predicate == null ? set : set.Where( predicate ) ); | |
return query.SingleOrDefault(); | |
} | |
public IReadOnlyList<T> List( Expression<Func<T, bool>> condition = null, Func<T, string> order = null ) | |
{ | |
var set = CreateSet(); | |
if( condition != null ) | |
{ | |
set = set.Where( condition ); | |
} | |
if( order != null ) | |
{ | |
return set.OrderBy( order ).ToList(); | |
} | |
return set.ToList(); | |
} | |
public int Count( Expression<Func<T, bool>> predicate = null ) | |
{ | |
var set = CreateSet(); | |
return ( predicate == null ? set.Count() : set.Count( predicate ) ); | |
} | |
public bool Exists( Expression<Func<T, bool>> predicate ) | |
{ | |
var set = CreateSet(); | |
return set.Any( predicate ); | |
} | |
} | |
public class DataContext | |
{ | |
string _mongoServerUrl; | |
string _mongoDbName; | |
MongoClient _client; | |
public DataContext( string dburl, string dbname ) | |
{ | |
_mongoServerUrl = dburl; | |
_mongoDbName = dbname; | |
_client = new MongoClient( _mongoServerUrl ); | |
} | |
public MongoDatabase GetDatabase() { return _client.GetServer().GetDatabase( _mongoDbName ); } | |
public void DropDatabase( string dbName ) | |
{ | |
var server = _client.GetServer(); | |
server.DropDatabase( dbName ); | |
} | |
public void DropCollection<T>() where T : IEntity<ObjectId> | |
{ | |
var database = GetDatabase(); | |
var collectionName = typeof( T ).Name.ToLower(); | |
if( database.CollectionExists( collectionName ) ) | |
{ | |
database.DropCollection( collectionName ); | |
} | |
} | |
} | |
public interface IEntity<T> | |
{ | |
T Id { get; set; } | |
bool Deleted { get; set; } | |
} | |
} |
What would you do with aggregations? I believe you only support composition, meaning objects contain the whole objects inside them, instead of keeping a reference inside. Is that right?
Hi bprhw, 'CreateNotdeletedSet()' was a refuse of an old code. I just updated it.
Sorry for delay of the answer :)
Hi Mahadi-K, you are right this example provides only composition support. I'm not sure that could be useful to have a reference to object when i'm working with non relational approach.
Hi antdimot, these code snippets are exactly what I was looking for.... Do you have a sample project where this pattern is implemented? Maybe in a WebApi?
Hi @ Skrappy , I have just released a project that use it.
I don't understand why do you need "Deleted" property in IEntity.
I don't understand why do you need "Deleted" property in IEntity.
Its for logical delete only.
Hi @antdimot. I just wonder, in your DataContext class you have a private var called _mongoDbName and you are setting it within the constructor.
Then for the "DropDatabase" method you are getting dbname as a parameter which may be out of db context. What is the purpose? Thanks.
You are right. The DataContext should not able to drop the database.
Hi, just giving this a go, what is the 'CreateNotdeletedSet()'? Only just trying it out, so sorry if you've covered this elsewhere?
Should it just be 'CreateSet()'?