Skip to content

Instantly share code, notes, and snippets.

@bhameyie
Created May 28, 2013 23:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhameyie/5666822 to your computer and use it in GitHub Desktop.
Save bhameyie/5666822 to your computer and use it in GitHub Desktop.
dynamic query builder
public class DynamicQueryBuilder : DynamicObject
{
private readonly string m_tableName;
private string internalQuery;
public DynamicQueryBuilder(string tableName)
{
m_tableName = tableName;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
var operation = binder.Name;
if (operation.Equals("All"))
{
result = All();
return true;
}
if (operation.StartsWith("FindAllBy"))
{
var column = operation.Substring("FindAllBy".Length);
if (binder.CallInfo.ArgumentCount != 1)
{
throw new ArgumentException("'FindAllBy' must be call with a single argument");
}
var argument = args.Single();
internalQuery = FindAllBy(column, Helper.WrapWithQuotes(argument));
result = this;
return true;
}
var prefix = string.IsNullOrEmpty(internalQuery) ? string.Empty : " ";
if (operation.Equals("Select"))
{
internalQuery += prefix + Select(args.Select(e => e.ToString()));
result = this;
return true;
}
if (operation.Equals("Where"))
{
if (binder.CallInfo.ArgumentCount < 1)
{
throw new ArgumentException("'Where' must be call with at least argument");
}
internalQuery += prefix + Where(args);
result = this;
return true;
}
throw new ArgumentException("Unsupported operation: " + operation);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = new DynamicColumn(binder.Name);
return true;
}
public override string ToString()
{
return internalQuery;
}
string Select(IEnumerable<string> columns)
{
return string.Format("Select {0} from {1}", string.Join(", ", columns), m_tableName);
}
string Where(params object[] expressions)
{
return string.Format("Where {0}", string.Join(" and ",expressions.Select(e=> e.ToString())));
}
string FindAllBy(string column, string value)
{
return string.Format("Select * from {0} Where {1} = {2}", m_tableName, column, value);
}
string All()
{
return "Select * from " + m_tableName;
}
}
static internal class Helper
{
static bool IsNumber(object argument)
{
return argument is int || argument is decimal || argument is float;
}
public static string WrapWithQuotes(object argument)
{
if (IsNumber(argument))
{
return argument.ToString();
}
return "\'" + argument.ToString().Replace("'", "''") + "'";//escaping quotes
}
}
public class DynamicColumn
{
public string Column { get; private set; }
public DynamicColumn(string column)
{
Column = column;
}
public static string operator ==(DynamicColumn column, DynamicColumn foo2)
{
return column == foo2.Column;
}
public static string operator !=(DynamicColumn column, DynamicColumn foo2)
{
return (column != foo2.Column);
}
public static string operator !=(DynamicColumn foo1, object foo2)
{
return string.Format("{0} != {1}", foo1.Column, Helper.WrapWithQuotes(foo2));
}
public static string operator ==(DynamicColumn foo1, object foo2)
{
return string.Format("{0} = {1}", foo1.Column, Helper.WrapWithQuotes(foo2));
}
public bool Equals(DynamicColumn other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Equals(other.Column, Column);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != typeof(DynamicColumn)) return false;
return Equals((DynamicColumn)obj);
}
public override int GetHashCode()
{
return (Column != null ? Column.GetHashCode() : 0);
}
public override string ToString()
{
return Column;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment