Created
August 19, 2010 17:29
-
-
Save mikeobrien/538426 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class MongoDbSandbox | |
{ | |
public static void Main() | |
{ | |
var repo = new MongoDbObjectRepository("mongodb://user:password@localhost/Test"); | |
var model = new Model {Number = 2}; | |
var user = repo.Fetch<User>(u => u.Number == model.GetNumber(45)); | |
Console.WriteLine(user != null ? user.Name : "Nothing found"); | |
Console.ReadKey(); | |
} | |
public class Model | |
{ | |
public int Number { get; set; } | |
public int GetNumber(int val) | |
{ | |
return val; | |
} | |
} | |
public class User | |
{ | |
public User() | |
{ | |
Id = Guid.NewGuid(); | |
} | |
public Guid Id { get; set; } | |
public int Number { get; set; } | |
public string Name { get; set; } | |
} | |
public class MongoDbObjectRepository | |
{ | |
private readonly string _connectionString; | |
public MongoDbObjectRepository(string connectionString) | |
{ | |
_connectionString = connectionString; | |
} | |
public TEntity Fetch<TEntity>(Expression<Func<TEntity, bool>> filter) | |
where TEntity : class, new() | |
{ | |
return Execute<TEntity>(c => c.FindOne( | |
FilterVisitor.CreateExpandoFromExpression(filter))); | |
} | |
// Other stuff ommitted for brevity.... | |
private TEntity Execute<TEntity>(Func<IMongoCollection<TEntity>, TEntity> function) where TEntity : class, new() | |
{ return Execute<TEntity, TEntity>(function); } | |
private TResult Execute<TEntity, TResult>(Func<IMongoCollection<TEntity>, TResult> function) where TEntity : class, new() | |
{ | |
using (var mongo = Mongo.Create(_connectionString)) | |
{ | |
return function(mongo.GetCollection<TEntity>()); | |
} | |
} | |
} | |
public class FilterVisitor : ExpressionVisitor | |
{ | |
private readonly Dictionary<string, object> | |
_filters = new Dictionary<string, object>(); | |
public IDictionary<string, object> Filters { get { return _filters; } } | |
public static Expando CreateExpandoFromExpression<TEntity>( | |
Expression<Func<TEntity, bool>> filterExpression) | |
{ | |
var filterVisitor = new FilterVisitor(); | |
filterVisitor.Visit(filterExpression); | |
var filterObject = new Expando(); | |
foreach (var filter in filterVisitor.Filters) | |
filterObject.Set(filter.Key, filter.Value); | |
return filterObject; | |
} | |
protected override Expression VisitBinary(BinaryExpression node) | |
{ | |
if (!(node.NodeType == ExpressionType.Equal || | |
node.NodeType == ExpressionType.And || | |
node.NodeType == ExpressionType.AndAlso)) | |
throw new Exception( | |
string.Format("{0} not supported. Use only Equal, And and AndAlso.", | |
node.NodeType)); | |
if (node.NodeType == ExpressionType.Equal) | |
{ | |
if (!(node.Left is MemberExpression)) | |
throw new Exception("Left side of the equation must be a member."); | |
object value = null; | |
if (node.Right is ConstantExpression) | |
value = ((ConstantExpression) node.Right).Value; | |
else if (node.Right is MemberExpression || node.Right is MethodCallExpression) | |
value = Expression.Lambda(node.Right).Compile().DynamicInvoke(); | |
else | |
throw new Exception("Right side of the equation must be a constant, member or method call."); | |
_filters.Add(((MemberExpression)node.Left).Member.Name, value); | |
} | |
return base.VisitBinary(node); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment