-
-
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; } | |
} | |
} |
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.
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?