public object Execute(Expression expression) { MethodCallExpression exp = expression as MethodCallExpression; aliasList = new Dictionary <MemberInfo, string>(); ReadExpressions(expression); try { if (doCount) { return(searchOptions.ExecuteCount()); } else { IList toReturn; if (searchOptions.Projections.Count == 0) { toReturn = searchOptions.Execute(); } else { object[][] items = searchOptions.ExecuteMatrix(); Type listof = typeof(List <>).MakeGenericType(elementType); IList list = (IList)Activator.CreateInstance(listof); foreach (object[] row in items) { object typedRow = null; if (projectionBindings == null) { if (searchOptions.Projections.Count == 1) { typedRow = row[0]; } else { typedRow = projectionCtor.Invoke(row); } } else { typedRow = projectionCtor.Invoke(null); for (int i = 0; i < projectionBindings.Count; i++) { FieldInfo field = projectionBindings[i].Member as FieldInfo; PropertyInfo prop = projectionBindings[i].Member as PropertyInfo; if (field != null) { field.SetValue(typedRow, row[i]); } else if (prop != null) { prop.SetValue(typedRow, row[i], null); } else { throw new NotImplementedException(string.Format("The member access of '{0}' is not implemented.", projectionBindings[i].Member.Name)); } } } list.Add(typedRow); } toReturn = list; } if (exp != null) { switch (exp.Method.Name) { case "Single": case "First": if (toReturn.Count > 1) { throw new InvalidOperationException("The input sequence contains more than one element."); } else if (toReturn.Count == 0) { throw new Tenor.Data.RecordNotFoundException(); } return(toReturn[0]); case "SingleOrDefault": case "FirstOrDefault": if (toReturn.Count > 1) { throw new InvalidOperationException("The input sequence contains more than one element."); } else if (toReturn.Count == 0) { return(null); } else { return(toReturn[0]); } default: return(toReturn); } } else { return(toReturn); } } } catch { throw; } finally { searchOptions = null; aliasList = null; } }
private void ReadExpressions(Expression ex) { switch (ex.NodeType) { case ExpressionType.Call: { MethodCallExpression mce = (MethodCallExpression)ex; //continue recursively ReadExpressions(mce.Arguments[0]); switch (mce.Method.Name) { /* LINQ Methods */ case "Where": //the where clause. ReadWhereExpressions(searchOptions.Conditions, mce.Arguments[1], false, null); break; case "ThenBy": case "OrderBy": ReadOrderByExpressions(mce.Arguments[1], true); break; case "ThenByDescending": case "OrderByDescending": ReadOrderByExpressions(mce.Arguments[1], false); break; case "Take": //the TOP/LIMIT function. int top = (int)((ConstantExpression)mce.Arguments[1]).Value; searchOptions.Top = top; break; case "SingleOrDefault": case "Single": //nothing to do here break; case "FirstOrDefault": case "First": searchOptions.Top = 1; break; case "Distinct": searchOptions.Distinct = true; break; case "Count": doCount = true; break; /* END LINQ */ /* TENOR LINQ Methods */ case "LoadAlso": ReadEager(mce.Arguments[1], null); break; /* END LINQ Methods */ case "Select": ReadSelect(mce.Arguments[1]); break; default: throw new NotImplementedException("Linq method call to '" + mce.Method.Name.ToString() + "' is not implemented. Please, send a feature request."); } } break; case ExpressionType.Constant: { ConstantExpression cex = (ConstantExpression)ex; IQueryable item = cex.Value as IQueryable; if (item != null) { Type[] t = item.GetType().GetGenericArguments(); searchOptions = new Tenor.Data.SearchOptions(t[0]); //searchOptions.LazyLoading = item.LazyLoading; } } break; default: throw new NotImplementedException("Linq '" + ex.NodeType.ToString() + "' is not implemented. Please, send a feature request."); } }