-
-
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()'?