public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
//parse the method
var constraints = new List<string>();
var counter = 0;
var info = binder.CallInfo;
// accepting named args only... SKEET!
if (info.ArgumentNames.Count != args.Length) {
throw new InvalidOperationException("Please use named arguments for this type of query - the column name, orderby, columns, etc");
}
//first should be "FindBy, Last, Single, First"
var op = binder.Name;
var columns = " * ";
string orderBy = string.Format(" ORDER BY {0}", PrimaryKeyField);
string sql = "";
string where = "";
var whereArgs = new List<object>();
//loop the named args - see if we have order, columns and constraints
if (info.ArgumentNames.Count > 0) {
for (int i = 0; i < args.Length; i++) {
var name = info.ArgumentNames[i].ToLower();
switch (name) {
case "orderby":
orderBy = " ORDER BY " + args[i];
break;
case "columns":
columns = args[i].ToString();
break;
default:
constraints.Add(string.Format(" {0} = @{1}", name, counter));
whereArgs.Add(args[i]);
counter++;
break;
}
}
}
//Build the WHERE bits
if (constraints.Count > 0) {
where = " WHERE " + string.Join(" AND ", constraints.ToArray());
}
//probably a bit much here but... yeah this whole thing needs to be refactored...
if (op.ToLower() == "count") {
result = Scalar("SELECT COUNT(*) FROM " + TableName + where, whereArgs.ToArray());
}
else if (op.ToLower() == "sum") {
result = Scalar("SELECT SUM(" + columns + ") FROM " + TableName + where, whereArgs.ToArray());
}
else if (op.ToLower() == "max") {
result = Scalar("SELECT MAX(" + columns + ") FROM " + TableName + where, whereArgs.ToArray());
}
else if (op.ToLower() == "min") {
result = Scalar("SELECT MIN(" + columns + ") FROM " + TableName + where, whereArgs.ToArray());
}
else if (op.ToLower() == "avg") {
result = Scalar("SELECT AVG(" + columns + ") FROM " + TableName + where, whereArgs.ToArray());
}
else {
//build the SQL
sql = "SELECT TOP 1 " + columns + " FROM " + TableName + where;
var justOne = op.StartsWith("First") || op.StartsWith("Last") || op.StartsWith("Get") || op.StartsWith("Single");
//Be sure to sort by DESC on the PK (PK Sort is the default)
if (op.StartsWith("Last")) {
orderBy = orderBy + " DESC ";
}
else {
//default to multiple
sql = "SELECT " + columns + " FROM " + TableName + where;
}
if (justOne) {
//return a single record
result = Query(sql + orderBy, whereArgs.ToArray()).FirstOrDefault();
}
else {
//return lots
result = Query(sql + orderBy, whereArgs.ToArray());
}
}
return true;
}