private static IDbSelectable CreateNewSelectableForWrappingSelect( IDbSelect dbSelect, IDbSelectable selectable, DbReference dbRef, Expression m, IDbObjectFactory dbFactory, UniqueNameGenerator nameGenerator) { if (dbRef == null) { return(selectable); } var oCol = selectable as IDbColumn; if (oCol != null) { return(dbFactory.BuildColumn(dbRef, oCol.GetAliasOrName(), oCol.ValType)); } var oRefCol = selectable as IDbRefColumn; if (oRefCol != null) { return(dbFactory.BuildRefColumn(dbRef, oRefCol.Alias, oRefCol)); } if (selectable is IDbFunc oDbFunc) { if (string.IsNullOrEmpty(oDbFunc.Alias)) { oDbFunc.Alias = nameGenerator.GenerateAlias(dbSelect, oDbFunc.Name, true); } return(dbFactory.BuildColumn(dbRef, oDbFunc.Alias, oDbFunc.ReturnType)); } return(dbFactory.BuildColumn(dbRef, selectable.Alias, typeof(string))); }
public static IDbSelectable[] ProcessSelection(IDbObject dbObj, IDbObjectFactory factory) { var dbList = dbObj as IDbList <DbKeyValue>; if (dbList != null) { var keyVals = dbList; return(keyVals.SelectMany(kv => ProcessSelection(kv, factory)).ToArray()); } var obj = dbObj as DbReference; if (obj != null) { var dbRef = obj; return(new IDbSelectable[] { factory.BuildRefColumn(dbRef, dbRef.RefColumnAlias) }); } var dbBinary = dbObj as IDbBinary; if (dbBinary != null && ( dbBinary.Operator == DbOperator.Equal || dbBinary.Operator == DbOperator.NotEqual || dbBinary.Operator == DbOperator.GreaterThan || dbBinary.Operator == DbOperator.GreaterThanOrEqual || dbBinary.Operator == DbOperator.LessThan || dbBinary.Operator == DbOperator.LessThanOrEqual || dbBinary.Operator == DbOperator.Is || dbBinary.Operator == DbOperator.IsNot)) { var dbTrue = factory.BuildConstant(true); var tuple = Tuple.Create <IDbBinary, IDbObject>(dbBinary, dbTrue); return(new IDbSelectable[] { factory.BuildCondition(new [] { tuple }, factory.BuildConstant(false)) }); } var keyValue = dbObj as DbKeyValue; if (keyValue == null) { return new[] { (IDbSelectable)dbObj } } ; var selectables = ProcessSelection(keyValue.Value, factory); foreach (var selectable in selectables) { selectable.Alias = keyValue.Key; } return(selectables); }
public static IDbSelectable[] ProcessSelection(IDbObject dbObj, IDbObjectFactory factory) { switch (dbObj) { case IDbList <DbKeyValue> dbList: var keyVals = dbList; return(keyVals.SelectMany(kv => ProcessSelection(kv, factory)).ToArray()); case DbReference obj: var dbRef = obj; return(new IDbSelectable[] { factory.BuildRefColumn(dbRef, dbRef.RefColumnAlias) }); case IDbBinary dbBinary when( dbBinary.Operator == DbOperator.Equal || dbBinary.Operator == DbOperator.NotEqual || dbBinary.Operator == DbOperator.GreaterThan || dbBinary.Operator == DbOperator.GreaterThanOrEqual || dbBinary.Operator == DbOperator.LessThan || dbBinary.Operator == DbOperator.LessThanOrEqual || dbBinary.Operator == DbOperator.Is || dbBinary.Operator == DbOperator.IsNot): var dbTrue = factory.BuildConstant(true); var tuple = Tuple.Create <IDbBinary, IDbObject>(dbBinary, dbTrue); return(new IDbSelectable[] { factory.BuildCondition(new [] { tuple }, factory.BuildConstant(false)) }); } if (!(dbObj is DbKeyValue keyValue)) { return new[] { (IDbSelectable)dbObj } } ; var selectables = ProcessSelection(keyValue.Value, factory); foreach (var selectable in selectables) { selectable.Alias = keyValue.Key; } return(selectables); }
private static IDbSelectable CreateNewSelectableForWrappingSelect( IDbSelectable selectable, DbReference dbRef, IDbObjectFactory dbFactory) { if (dbRef == null) { return(selectable); } var oCol = selectable as IDbColumn; if (oCol != null) { return(dbFactory.BuildColumn(dbRef, oCol.GetAliasOrName(), oCol.ValType)); } var oRefCol = selectable as IDbRefColumn; if (oRefCol != null) { return(dbFactory.BuildRefColumn(dbRef, oRefCol.Alias, oRefCol)); } return(dbFactory.BuildColumn(dbRef, selectable.Alias, typeof(string))); }
protected override Expression VisitMember(MemberExpression m) { var expression = Visit(m.Expression); if (expression is ConstantExpression constExpr) { var container = constExpr.Value; var member = m.Member; object value = null; var valueRetrieved = false; switch (member) { case FieldInfo field: value = field.GetValue(container); valueRetrieved = true; break; case PropertyInfo prop: value = prop.GetValue(container, null); valueRetrieved = true; break; } if (valueRetrieved) { var dbObject = _dbFactory.BuildConstant(value, true); _state.ResultStack.Push(dbObject); return(m); } } var typeInfo = m.Type.GetTypeInfo(); if (m.Expression.Type.IsAnonymouse()) { var dbRef = (DbReference)_state.ResultStack.Peek(); if (dbRef.RefSelection.ContainsKey(m.Member.Name)) { var dbObj = dbRef.RefSelection[m.Member.Name]; // pop out the dbRef from the stack, it was the result of // translate a parameter, and it is not required for following translation _state.ResultStack.Pop(); _state.ResultStack.Push(dbObj); return(m); } } if (m.Expression.Type.IsGrouping()) { var dbRef = (DbReference)_state.ResultStack.Pop(); var dbSelect = dbRef.OwnerSelect; if (dbSelect.GroupBys.IsSingleKey) { var kColumn = dbSelect.GroupBys.Single(); _state.ResultStack.Push(kColumn); } else { _state.ResultStack.Push(dbRef); } return(m); } // if the member is a queryable entity, we need to translate it // into a relation, which means a join var entityInfo = _infoProvider.FindEntityInfo(m.Type); if (entityInfo != null) { var dbObj = _state.ResultStack.Pop(); var refCol = dbObj as IDbRefColumn; var fromRef = refCol != null ? refCol.Ref : (DbReference)dbObj; var fromEntity = _infoProvider.FindEntityInfo(m.Expression.Type); var relation = fromEntity.GetRelation(m.Member.Name); var dbJoin = GetOrCreateJoin(relation, fromRef, refCol ?? fromRef.ReferredRefColumn); // RefColumnAlias is used as alias in case we need to create a ref column for this dbRef dbJoin.To.RefColumnAlias = m.Member.Name; if (refCol != null) { refCol = _dbFactory.BuildRefColumn(dbJoin.To, m.Member.Name); if (dbJoin.To.Referee is IDbSelect subSelect) { refCol.RefTo = subSelect.Selection.OfType <IDbRefColumn>().Single(); } _state.ResultStack.Push(refCol); return(m); } _state.ResultStack.Push(relation.IsChildRelation ? dbJoin.To.Referee : dbJoin.To); return(m); } if (typeInfo.Namespace.StartsWith("System")) { var dbObj = _state.ResultStack.Pop(); var refCol = dbObj as IDbRefColumn; var dbRef = refCol != null ? refCol.Ref : (DbReference)dbObj; var fieldInfo = _infoProvider.FindFieldInfo(m.Member); var col = _dbFactory.BuildColumn(dbRef, fieldInfo.DbName, fieldInfo.ValType); _state.ResultStack.Push(col); // if we create a column whose DbRef is using by a RefColumn // we need to make sure the column is added to the ref column's owner select // This normally happen when we are accessing a column from a child relation refCol = refCol ?? dbRef.ReferredRefColumn; // if the ref column is not now, and it is referring another ref column // we need to make sure the column we translated is in the sub select which // owns the ref column that referred by the current refColumn refCol?.RefTo?.AddToReferedSelect(_dbFactory, fieldInfo.DbName, fieldInfo.ValType); return(m); } return(base.VisitMember(m)); }