Skip to content

Instantly share code, notes, and snippets.

@mikeobrien
Created August 19, 2010 17:29
Show Gist options
  • Save mikeobrien/538426 to your computer and use it in GitHub Desktop.
Save mikeobrien/538426 to your computer and use it in GitHub Desktop.
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