public override void Visit(DbPropertyExpression e) { Check.NotNull <DbPropertyExpression>(e, nameof(e)); e.Instance.Accept((DbExpressionVisitor)this); this.VisitExprKind(e.ExpressionKind); this._key.Append(e.Property.Name); }
public override VisitedExpression Visit(DbPropertyExpression expression) { DbVariableReferenceExpression variable = expression.Instance as DbVariableReferenceExpression; if (variable == null || variable.VariableName != _projectVarName.Peek()) throw new NotSupportedException(); return new PropertyExpression(expression.Property); }
/// <summary>Implements the visitor pattern for retrieving an instance property.</summary> /// <param name="expression">The expression.</param> /// <returns>The implemented visitor.</returns> public override DbExpression Visit(DbPropertyExpression expression) { var baseExpression = base.Visit(expression); var baseExpressionProperty = baseExpression as DbPropertyExpression; if (baseExpressionProperty == null) { return(baseExpression); } var navProp = baseExpressionProperty.Property as NavigationProperty; if (navProp != null && baseExpression.ResultType.ToString().Contains("Transient.collection[")) { var targetEntityType = navProp.ToEndMember.GetEntityType(); var fullName = targetEntityType.FullName; baseExpression = ApplyFilter(baseExpression, fullName); } else if (QueryFilterManager.AllowPropertyFilter && navProp != null) { var targetEntityType = navProp.ToEndMember.GetEntityType(); var fullName = targetEntityType.FullName; baseExpression = ApplyFilter(baseExpression, fullName); } return(baseExpression); }
internal static bool TryMatchPropertyEqualsValue( DbExpression expression, string propertyVariable, out DbPropertyExpression property, out object value) { property = null; value = null; // make sure when is of the form Discriminator = Constant if (expression.ExpressionKind != DbExpressionKind.Equals) { return(false); } var equals = (DbBinaryExpression)expression; if (equals.Left.ExpressionKind != DbExpressionKind.Property) { return(false); } property = (DbPropertyExpression)equals.Left; if (!TryMatchConstant(equals.Right, out value)) { return(false); } // verify the property is a property of the input variable if (property.Instance.ExpressionKind != DbExpressionKind.VariableReference || ((DbVariableReferenceExpression)property.Instance).VariableName != propertyVariable) { return(false); } return(true); }
public override DbExpression Visit(DbPropertyExpression expression) { Check.NotNull <DbPropertyExpression>(expression, nameof(expression)); DbExpression dbExpression; return(expression.Instance.ExpressionKind != DbExpressionKind.VariableReference || !(((DbVariableReferenceExpression)expression.Instance).VariableName == this.variableName) || !this.replacements.TryGetValue(expression.Property.Name, out dbExpression) ? base.Visit(expression) : dbExpression); }
public override TreeNode Visit(DbPropertyExpression e) { Check.NotNull <DbPropertyExpression>(e, nameof(e)); TreeNode treeNode1 = (TreeNode)null; if (e.Instance != null) { treeNode1 = this.VisitExpression(e.Instance); if (e.Instance.ExpressionKind == DbExpressionKind.VariableReference || e.Instance.ExpressionKind == DbExpressionKind.Property && treeNode1.Children.Count == 0) { treeNode1.Text.Append("."); treeNode1.Text.Append(e.Property.Name); return(treeNode1); } } TreeNode treeNode2 = new TreeNode(".", new TreeNode[0]); EdmProperty property = e.Property as EdmProperty; if (property != null && !(property.DeclaringType is RowType)) { ExpressionPrinter.PrinterVisitor.AppendFullName(treeNode2.Text, (EdmType)property.DeclaringType); treeNode2.Text.Append("."); } treeNode2.Text.Append(e.Property.Name); if (treeNode1 != null) { treeNode2.Children.Add(new TreeNode("Instance", new TreeNode[1] { treeNode1 })); } return(treeNode2); }
// <summary> // Determines whether two expressions match. // They match if they are of the shape // expr1 -> DbPropertyExpression(... (DbPropertyExpression(DbVariableReferenceExpression(expr1BindingVariableName), nameX), ..., name1) // expr1 -> DbPropertyExpression(... (DbPropertyExpression(DbVariableReferenceExpression(expr2BindingVariableName), nameX), ..., name1), // i.e. if they only differ in the name of the binding. // </summary> private static bool AreMatching( DbPropertyExpression expr1, DbPropertyExpression expr2, string expr1BindingVariableName, string expr2BindingVariableName) { if (expr1.Property.Name != expr2.Property.Name) { return(false); } if (expr1.Instance.ExpressionKind != expr2.Instance.ExpressionKind) { return(false); } if (expr1.Instance.ExpressionKind == DbExpressionKind.Property) { return(AreMatching( (DbPropertyExpression)expr1.Instance, (DbPropertyExpression)expr2.Instance, expr1BindingVariableName, expr2BindingVariableName)); } var instance1 = (DbVariableReferenceExpression)expr1.Instance; var instance2 = (DbVariableReferenceExpression)expr2.Instance; return(String.Equals(instance1.VariableName, expr1BindingVariableName, StringComparison.Ordinal) && String.Equals(instance2.VariableName, expr2BindingVariableName, StringComparison.Ordinal)); }
public override SqlFragment Visit(DbPropertyExpression expression) { propertyLevel++; PropertyFragment fragment = expression.Instance.Accept(this) as PropertyFragment; fragment.Properties.Add(expression.Property.Name); propertyLevel--; // if we are not at the top level property then just return if (propertyLevel > 0) { return(fragment); } // we are at the top level property so now we can do our work ColumnFragment column = GetColumnFromPropertyTree(fragment); for (int i = fragment.Properties.Count - 1; i >= 0; --i) { InputFragment inputFragment = scope.GetFragment(fragment.Properties[i]); if (inputFragment != null) { column.TableAlias = inputFragment.Name; break; } } return(column); }
public override void Visit(DbPropertyExpression expression) { Check.NotNull(expression, "expression"); _commandText.Append(GenerateMemberTSql(expression.Property)); }
private string GetValue(DbPropertyExpression prop, DbConstantExpression val) { var dbCastExpression = val.CastTo(prop.Property.TypeUsage); var value = dbCastExpression.ToString(); return(value); }
public override void Visit(DbPropertyExpression e) { Check.NotNull(e, "e"); // // Currently the DbPropertyExpression.EdmProperty member property may only be either: // - EdmProperty // - RelationshipEndMember // - NavigationProperty // Begin(e); var end = e.Property as RelationshipEndMember; if (end != null) { Dump(end, "Property"); } else if (Helper.IsNavigationProperty(e.Property)) { Dump((NavigationProperty)e.Property, "Property"); } else { Dump((EdmProperty)e.Property); } if (e.Instance != null) { Dump(e.Instance, "Instance"); } End(e); }
public override TreeNode Visit(DbPropertyExpression e) { TreeNode inst = null; if (e.Instance != null) { inst = this.VisitExpression(e.Instance); if (e.Instance.ExpressionKind == DbExpressionKind.VariableReference || (e.Instance.ExpressionKind == DbExpressionKind.Property && 0 == inst.Children.Count)) { inst.Text.Append("."); inst.Text.Append(e.Property.Name); return(inst); } } TreeNode retInfo = new TreeNode("."); EdmProperty prop = e.Property as EdmProperty; if (prop != null && !(prop.DeclaringType is RowType)) { // Entity, Relationship, Complex AppendFullName(retInfo.Text, prop.DeclaringType); retInfo.Text.Append("."); } retInfo.Text.Append(e.Property.Name); if (inst != null) { retInfo.Children.Add(new TreeNode("Instance", inst)); } return(retInfo); }
public override VisitedExpression Visit(DbPropertyExpression expression) { /* * Algorithm for finding the correct reference expression: "Collection"."Name" * The collection is always a leaf InputExpression, found by lookup in _refToNode. * The name for the collection is found using node.TopName. * * We must now follow the path from the leaf down to the root, * and make sure the column is projected all the way down. * * We need not project columns at a current InputExpression. * For example, in * SELECT ? FROM <from> AS "X" WHERE "X"."field" = <value> * we use the property "field" but it should not be projected. * Current expressions are stored in _currentExpressions. * There can be many of these, for example if we are in a WHERE EXISTS (SELECT ...) or in the right hand side of an Apply expression. * * At join nodes, column names might have to be renamed, if a name collision occurs. * For example, the following would be illegal, * SELECT "X"."A" AS "A", "Y"."A" AS "A" FROM (SELECT 1 AS "A") AS "X" CROSS JOIN (SELECT 1 AS "A") AS "Y" * so we write * SELECT "X"."A" AS "A", "Y"."A" AS "A_Alias<N>" FROM (SELECT 1 AS "A") AS "X" CROSS JOIN (SELECT 1 AS "A") AS "Y" * The new name is then propagated down to the root. */ string name = expression.Property.Name; string from = (expression.Instance.ExpressionKind == DbExpressionKind.Property) ? ((DbPropertyExpression)expression.Instance).Property.Name : ((DbVariableReferenceExpression)expression.Instance).VariableName; PendingProjectsNode node = _refToNode[from]; from = node.TopName; while (node != null) { foreach (var item in node.Selects) { if (_currentExpressions.Contains(item.Exp)) continue; var use = new StringPair(from, name); if (!item.Exp.ColumnsToProject.ContainsKey(use)) { var oldName = name; while (item.Exp.ProjectNewNames.Contains(name)) name = oldName + "_" + NextAlias(); item.Exp.ColumnsToProject[use] = name; item.Exp.ProjectNewNames.Add(name); } else { name = item.Exp.ColumnsToProject[use]; } from = item.AsName; } node = node.JoinParent; } return new ColumnReferenceExpression { Variable = from, Name = name }; }
public override void Visit(DbPropertyExpression e) { Check.NotNull(e, "e"); e.Instance.Accept(this); VisitExprKind(e.ExpressionKind); _key.Append(e.Property.Name); }
public override void Visit(DbPropertyExpression expression) { Write(expression); _depth++; Write("Name", expression.Property.Name); Write("Instance", expression.Instance); _depth--; }
public override DbExpression Visit(DbPropertyExpression expression) { DebugCheck.NotNull(expression); _currentProperty = (EdmProperty)expression.Property; return(base.Visit(expression)); }
/// <summary> /// This method handles record flattening, which works as follows. /// consider an expression <c>Prop(y, Prop(x, Prop(d, Prop(c, Prop(b, Var(a)))))</c> /// where a,b,c are joins, d is an extent and x and y are fields. /// b has been flattened into a, and has its own SELECT statement. /// c has been flattened into b. /// d has been flattened into c. /// /// We visit the instance, so we reach Var(a) first. This gives us a (join)symbol. /// Symbol(a).b gives us a join symbol, with a SELECT statement i.e. Symbol(b). /// From this point on , we need to remember Symbol(b) as the source alias, /// and then try to find the column. So, we use a SymbolPair. /// /// We have reached the end when the symbol no longer points to a join symbol. /// </summary> /// <param name="e"></param> /// <returns>A <see cref="JoinSymbol"/> if we have not reached the first /// Join node that has a SELECT statement. /// A <see cref="SymbolPair"/> if we have seen the JoinNode, and it has /// a SELECT statement. /// A <see cref="SqlBuilder"/> with {Input}.propertyName otherwise. /// </returns> public override ISqlFragment Visit(DbPropertyExpression e) { var instanceSql = e.Instance.Accept(this); // Since the DbVariableReferenceExpression is a proper child of ours, we can reset // isVarSingle. if (e.Instance is DbVariableReferenceExpression) { isVarRefSingle = false; } // We need to flatten, and have not yet seen the first nested SELECT statement. if (instanceSql is JoinSymbol) { var joinSymbol = (JoinSymbol)instanceSql; Debug.Assert(joinSymbol.NameToExtent.ContainsKey(e.Property.Name)); if (joinSymbol.IsNestedJoin) { return(new SymbolPair(joinSymbol, joinSymbol.NameToExtent[e.Property.Name])); } else { return(joinSymbol.NameToExtent[e.Property.Name]); } } // --------------------------------------- // We have seen the first nested SELECT statement, but not the column. if (instanceSql is SymbolPair) { SymbolPair symbolPair = (SymbolPair)instanceSql; if (symbolPair.Column is JoinSymbol) { symbolPair.Column = ((JoinSymbol)symbolPair.Column).NameToExtent[e.Property.Name]; return(symbolPair); } else { // symbolPair.Column has the base extent. // we need the symbol for the column, since it might have been renamed // when handling a JOIN. if (symbolPair.Column.Columns.ContainsKey(e.Property.Name)) { return(new SqlBuilder(symbolPair.Source, ".", symbolPair.Column.Columns[e.Property.Name])); } } } // --------------------------------------- if (instanceSql is Symbol) { return(new ColumnSymbol((Symbol)instanceSql, new Symbol(e.Property.Name, null))); } // At this point the column name cannot be renamed, so we do // not use a symbol. return(new SqlBuilder(instanceSql, ".", QuoteIdentifier(e.Property.Name))); }
public override VisitedExpression Visit(DbPropertyExpression expression) { // not quite sure what this does // may be . notation for seperating // scopes (such as schema.table.column) //VisitedExpression variable = expression.Instance.Accept(this); VariableReferenceExpression variable = new VariableReferenceExpression(expression.Instance.Accept(this).ToString(), _variableSubstitution); return new PropertyExpression(variable, expression.Property); }
/// <summary> /// Implements the visitor pattern for <see cref="T:System.Data.Common.CommandTrees.DbPropertyExpression"/>. /// </summary> /// <param name="expression">The <see cref="T:System.Data.Common.CommandTrees.DbPropertyExpression"/> that is visited.</param> public override void Visit(DbPropertyExpression expression) { if (expression == null) { throw new ArgumentNullException("expression"); } expression.Instance.Accept(this); }
public override DbExpression Visit(DbPropertyExpression property) { Check.NotNull <DbPropertyExpression>(property, nameof(property)); if (property.Instance.ExpressionKind == DbExpressionKind.VariableReference && this.IsOuterBindingVarRef((DbVariableReferenceExpression)property.Instance)) { return(this.m_varRefMemberBindings[property.Property.Name]); } return(base.Visit(property)); }
public override void Visit(DbPropertyExpression expression) { EntityUtils.CheckArgumentNull <DbPropertyExpression>(expression, nameof(expression)); if (expression.Instance == null) { return; } this.VisitExpression(expression.Instance); }
public override void Visit(DbPropertyExpression expression) { if (!string.IsNullOrEmpty(this.PropertyAlias)) { _commandText.Append(this.PropertyAlias); _commandText.Append("."); } _commandText.Append(GenerateMemberTSql(expression.Property)); }
public override VisitedExpression Visit(DbPropertyExpression expression) { // not quite sure what this does // may be . notation for seperating // scopes (such as schema.table.column) //VisitedExpression variable = expression.Instance.Accept(this); VariableReferenceExpression variable = new VariableReferenceExpression(expression.Instance.Accept(this).ToString(), _variableSubstitution); return(new PropertyExpression(variable, expression.Property)); }
/// <summary> /// Visitor pattern method for <see cref="DbPropertyExpression" />. /// </summary> /// <param name="expression"> The DbPropertyExpression that is being visited. </param> /// <exception cref="ArgumentNullException"> /// <paramref name="expression" /> /// is null /// </exception> public override void Visit(DbPropertyExpression expression) { // #433613: PreSharp warning 56506: Parameter 'expression' to this public method must be validated: A null-dereference can occur here. Check.NotNull(expression, "expression"); if (expression.Instance != null) { VisitExpression(expression.Instance); } }
public override DbExpressionEntitySetInfo Visit(DbPropertyExpression expression) { DbExpressionStructuralTypeEntitySetInfo setInfos = VisitExpression(expression.Instance) as DbExpressionStructuralTypeEntitySetInfo; if (setInfos != null) { return(setInfos.GetEntitySetInfoForMember(expression.Property.Name)); } return(null); }
public override void Visit(DbPropertyExpression expression) { Check.NotNull <DbPropertyExpression>(expression, nameof(expression)); base.Visit(expression); if (expression.Property.BuiltInTypeKind == BuiltInTypeKind.EdmProperty) { return; } this._errors.Add(new EdmSchemaError(Strings.Mapping_UnsupportedPropertyKind_QueryView((object)this._setMapping.Set.Name, (object)expression.Property.Name, (object)expression.Property.BuiltInTypeKind), 2073, EdmSchemaErrorSeverity.Error, this._setMapping.EntityContainerMapping.SourceLocation, this._setMapping.StartLineNumber, this._setMapping.StartLinePosition)); }
public override VisitedExpression Visit(DbPropertyExpression expression) { DbVariableReferenceExpression variable = expression.Instance as DbVariableReferenceExpression; if (variable == null || variable.VariableName != _projectVarName.Peek()) { throw new NotSupportedException(); } return(new PropertyExpression(expression.Property)); }
public override DbExpression Visit(DbPropertyExpression property) { // check for a property of the outer projection binding (that can be remapped) if (property.Instance.ExpressionKind == DbExpressionKind.VariableReference && IsOuterBindingVarRef((DbVariableReferenceExpression)property.Instance)) { return(m_varRefMemberBindings[property.Property.Name]); } return(base.Visit(property)); }
public override void Visit(DbPropertyExpression expression) { Check.NotNull <DbPropertyExpression>(expression, nameof(expression)); if (!string.IsNullOrEmpty(this.PropertyAlias)) { this._commandText.Append(this.PropertyAlias); this._commandText.Append("."); } this._commandText.Append(DmlSqlGenerator.GenerateMemberTSql(expression.Property)); }
public override void Visit(DbPropertyExpression expression) { base.Visit(expression); if (expression.Property.BuiltInTypeKind != BuiltInTypeKind.EdmProperty) { _errors.Add(new EdmSchemaError(System.Data.Entity.Strings.Mapping_UnsupportedPropertyKind_QueryView( _setMapping.Set.Name, expression.Property.Name, expression.Property.BuiltInTypeKind), (int)StorageMappingErrorCode.MappingUnsupportedPropertyKindQueryView, EdmSchemaErrorSeverity.Error, _setMapping.EntityContainerMapping.SourceLocation, _setMapping.StartLineNumber, _setMapping.StartLinePosition)); } }
private DiscriminatorMap(DbPropertyExpression discriminator, List <KeyValuePair <object, EntityType> > typeMap, Dictionary <EdmProperty, DbExpression> propertyMap, Dictionary <Query.InternalTrees.RelProperty, DbExpression> relPropertyMap, EntitySet entitySet) { this.Discriminator = discriminator; this.TypeMap = typeMap.AsReadOnly(); this.PropertyMap = propertyMap.ToList().AsReadOnly(); this.RelPropertyMap = relPropertyMap.ToList().AsReadOnly(); this.EntitySet = entitySet; }
private DiscriminatorMap(DbPropertyExpression discriminator, List<KeyValuePair<object, EntityType>> typeMap, Dictionary<EdmProperty, DbExpression> propertyMap, Dictionary<Query.InternalTrees.RelProperty, DbExpression> relPropertyMap, EntitySet entitySet) { this.Discriminator = discriminator; this.TypeMap = typeMap.AsReadOnly(); this.PropertyMap = propertyMap.ToList().AsReadOnly(); this.RelPropertyMap = relPropertyMap.ToList().AsReadOnly(); this.EntitySet = entitySet; }
public override void Visit(DbPropertyExpression propertyExpression) { this._select.Append(this._currentTableAlias); this._select.Append("."); this._select.Append(SqlGenerator.QuoteIdentifier(propertyExpression.Property.Name)); if (string.IsNullOrWhiteSpace(this._nextPropertyAlias) || string.Equals(this._nextPropertyAlias, propertyExpression.Property.Name, StringComparison.Ordinal)) { return; } this._select.Append(" AS "); this._select.Append(this._nextPropertyAlias); }
private DbSetClause GetInsertSetClause(string column, DbExpression newValueToSetToDb, DbInsertCommandTree insertCommand) { // Create the variable reference in order to create the property DbVariableReferenceExpression variableReference = DbExpressionBuilder.Variable(insertCommand.Target.VariableType, insertCommand.Target.VariableName); // Create the property to which will assign the correct value DbPropertyExpression tenantProperty = DbExpressionBuilder.Property(variableReference, column); // Create the set clause, object representation of sql insert command DbSetClause newSetClause = DbExpressionBuilder.SetClause(tenantProperty, newValueToSetToDb); return(newSetClause); }
private DiscriminatorMap( DbPropertyExpression discriminator, List<KeyValuePair<object, EntityType>> typeMap, Dictionary<EdmProperty, DbExpression> propertyMap, Dictionary<RelProperty, DbExpression> relPropertyMap, EntitySet entitySet) { Discriminator = discriminator; TypeMap = new ReadOnlyCollection<KeyValuePair<object, EntityType>>(typeMap); PropertyMap = new ReadOnlyCollection<KeyValuePair<EdmProperty, DbExpression>>(propertyMap.ToList()); RelPropertyMap = new ReadOnlyCollection<KeyValuePair<RelProperty, DbExpression>>(relPropertyMap.ToList()); EntitySet = entitySet; }
private DiscriminatorMap( DbPropertyExpression discriminator, List<KeyValuePair<object, EntityType>> typeMap, Dictionary<EdmProperty, DbExpression> propertyMap, Dictionary<RelProperty, DbExpression> relPropertyMap, EntitySet entitySet) { Discriminator = discriminator; TypeMap = typeMap.AsReadOnly(); PropertyMap = propertyMap.ToList().AsReadOnly(); RelPropertyMap = relPropertyMap.ToList().AsReadOnly(); EntitySet = entitySet; }
public override Expression Visit(DbPropertyExpression expression) { string propertyName = expression.Property.GetColumnName(); Expression sourceExpression = this.Visit(expression.Instance); Expression result = Expression.Property(sourceExpression, propertyName); // Every property access result is nullable in SQL // Check if the propery type is not nullable if (result.Type.IsValueType && !TypeHelper.IsNullable(result.Type)) { // Make it nullable result = Expression.Convert(result, TypeHelper.MakeNullable(result.Type)); } return result; }
public override VisitedExpression Visit(DbPropertyExpression expression) { DbVariableReferenceExpression variable = expression.Instance as DbVariableReferenceExpression; if (variable == null || variable.VariableName != _projectVarName.Peek()) throw new NotSupportedException(); if (!_processingReturning) { return new PropertyExpression(expression.Property); } else { // the table name needs to be quoted, the column name does not. // http://archives.postgresql.org/pgsql-bugs/2007-01/msg00102.php string tableName = QuoteIdentifier(_variableSubstitution[variable.VariableName]); if (variable.VariableName == _commandTree.Target.VariableName) { // try to get the table name schema qualified. DbScanExpression scan = _commandTree.Target.Expression as DbScanExpression; if (scan != null) { #if ENTITIES6 System.Data.Entity.Core.Metadata.Edm.MetadataProperty metadata; #else System.Data.Metadata.Edm.MetadataProperty metadata; #endif string overrideSchema = "http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator:Schema"; if (scan.Target.MetadataProperties.TryGetValue(overrideSchema, false, out metadata) && metadata.Value != null) { tableName = QuoteIdentifier(metadata.Value.ToString()) + "." + tableName; } else if (scan.Target.MetadataProperties.TryGetValue("Schema", false, out metadata) && metadata.Value != null) { tableName = QuoteIdentifier(metadata.Value.ToString()) + "." + tableName; } else { tableName = QuoteIdentifier(scan.Target.EntityContainer.Name) + "." + tableName; } } } return new LiteralExpression("currval(pg_get_serial_sequence('" + tableName + "', '" + expression.Property.Name + "'))"); } }
// This is called for any navigation property reference so we can apply filters for those entities here. // That includes any navigation properties referenced in functions (.Where() clauses) and also any // child entities that are .Include()'d. public override DbExpression Visit(DbPropertyExpression expression) { #if DEBUG_VISITS System.Diagnostics.Debug.Print("Visit(DbPropertyExpression): EdmType.Name={0}", expression.ResultType.ModelTypeUsage.EdmType.Name); #endif var baseResult = base.Visit(expression); var basePropertyResult = baseResult as DbPropertyExpression; if (basePropertyResult == null) return baseResult; // base.Visit changed type! var navProp = basePropertyResult.Property as NavigationProperty; if (navProp != null) { var targetEntityType = navProp.ToEndMember.GetEntityType(); var containers = _ObjectContext.MetadataWorkspace.GetItems<EntityContainer>(DataSpace.CSpace).First(); var filterList = FindFiltersForEntitySet(targetEntityType.MetadataProperties); if (filterList.Any()) { // If the expression contains a collection (i.e. the child property is an IEnumerable), we can bind directly to it. // Otherwise, we have to create a DbScanExpression over the ResultType in order to bind. if (baseResult.ResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType) { var binding = DbExpressionBuilder.Bind(baseResult); var newFilterExpression = BuildFilterExpressionWithDynamicFilters(filterList, binding, null); if (newFilterExpression != null) { // If not null, a new DbFilterExpression has been created with our dynamic filters. return newFilterExpression; } } else if (baseResult.ResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType) { if (DoesNotSupportElementMethod(_DbContext)) { // Oracle and MySQL do not support the "newFilterExpression.Element()" method that we need to call // at the end of this block. Oracle *MAY* support it in a newer release but not sure // (see https://community.oracle.com/message/10168766#10168766). // But users may not have the option of upgrading their database so decided to try to support it. // If we find it is supported by newer versions, can detect those versions and allow the normal handling. // To apply any necessary filters to these entities, we're going to have to do it using SSpace. // These entities will be visited via the DbScan visit method so we will apply filters there. // If one of those filters then references a child property, the filter will fail. return baseResult; } DbExpression scanExpr; var entitySet = containers.EntitySets.FirstOrDefault(e => e.ElementType.Name == baseResult.ResultType.EdmType.Name); if (entitySet == null) { if (baseResult.ResultType.EdmType.BaseType == null) throw new ApplicationException(string.Format("EntitySet not found for {0}", baseResult.ResultType.EdmType.Name)); // Did not find the entity set for the property but it has a base type. // This means the entity set of the property is a derived class of a TPT base class. // Find the entity set of the parent and then map it to the type we need. // Then we can bind against that expression. entitySet = containers.EntitySets.FirstOrDefault(e => e.ElementType.Name == baseResult.ResultType.EdmType.BaseType.Name); if (entitySet == null) // hope we don't need to do this recursively... throw new ApplicationException(string.Format("EntitySet not found for {0} or BaseType {1}", baseResult.ResultType.EdmType.Name, baseResult.ResultType.EdmType.BaseType.Name)); var parentScanExpr = DbExpressionBuilder.Scan(entitySet); scanExpr = DbExpressionBuilder.OfType(parentScanExpr, baseResult.ResultType); } else scanExpr = DbExpressionBuilder.Scan(entitySet); var binding = DbExpressionBuilder.Bind(scanExpr); // Build the join conditions that are needed to join from the source object (basePropertyResult.Instance) // to the child object (the scan expression we just creating the binding for). // These conditions will be and'd with the filter conditions. var associationType = navProp.RelationshipType as AssociationType; if (associationType == null) throw new ApplicationException(string.Format("Unable to find AssociationType on navigation property of single child property {0} in type {1}", navProp.Name, navProp.DeclaringType.FullName)); if (associationType.Constraint == null) { // KNOWN_ISSUE: // If this happens, the model does not contain the foreign key (the "id" property). EF will automatically generate // it based on naming rules when generating the SSpace/database models but does not expose the Constraint here in the // AssociationType. In order for us to be able to generate the conditions correctly, those Foreign Keys need to be // specified on the model. To fix/handle this, we would need to examine the SSpace Association Sets (which do have // these relations!!) to try to map that information back to CSpace to figure out the correct properties of the FK conditions. // or...the models just need to contain the necessary "ID" properties for the FK relations so that they are available here // (in CSpace) for us to generate the necessary join conditions. throw new ApplicationException(string.Format("FK Constriant not found for association '{0}' - must directly specify foreign keys on model to be able to apply this filter", associationType.FullName)); } // Figure out if the "baseResults" are the from side or to side of the constraint so we can create the properties correctly // Note that this navigation property may be the same type as parent entity (so both association types // will be the same type). In that case, we need to figure out which side of the association matches the // PKs of the main entity. var fromEdmType = ((AssociationEndMember)associationType.Constraint.FromRole).GetEntityType(); var toEdmType = ((AssociationEndMember)associationType.Constraint.ToRole).GetEntityType(); bool baseResultIsFromRole; if (fromEdmType != toEdmType) baseResultIsFromRole = (basePropertyResult.Instance.ResultType.EdmType == fromEdmType); else { // When same, basePropertyResult is the child property and binding is the main entity. // Fixes issue #85. baseResultIsFromRole = false; } DbExpression joinCondition = null; for (int i = 0; i < associationType.Constraint.FromProperties.Count; i++) { var prop1 = DbExpressionBuilder.Property(basePropertyResult.Instance, baseResultIsFromRole ? associationType.Constraint.FromProperties[i] : associationType.Constraint.ToProperties[i]); var prop2 = DbExpressionBuilder.Property(binding.Variable, baseResultIsFromRole ? associationType.Constraint.ToProperties[i] : associationType.Constraint.FromProperties[i]); var condition = prop1.Equal(prop2) as DbExpression; joinCondition = (joinCondition == null) ? condition : joinCondition.And(condition); } // Translate the filter predicate into a DbExpression bound to the Scan expression of the target entity set. // Those conditions are then and'd with the join conditions necessary to join the target table with the source table. var newFilterExpression = BuildFilterExpressionWithDynamicFilters(filterList, binding, joinCondition); if (newFilterExpression != null) { // Converts the collection results into a single row. The expected output is a single item so EF will // then populate the results of that query into the property in the model. // The resulting SQL will be a normal "left outer join" just as it would normally be except that our // filter predicate conditions will be included with the normal join conditions. // MySQL needs this Limit() applied here or it throws an error saying: // Unable to cast object of type 'MySql.Data.Entity.SelectStatement' to type 'MySql.Data.Entity.LiteralFragment'. // But don't do that unless necessary because it produces extra "outer apply" sub queries in MS SQL. // This trick does not work for Oracle... if (_DbContext.IsMySql()) return newFilterExpression.Limit(DbConstantExpression.FromInt32(1)).Element(); return newFilterExpression.Element(); } } } } return baseResult; }
public override void Visit(DbPropertyExpression expression) { }
internal static bool TryMatchPropertyEqualsValue(DbExpression expression, string propertyVariable, out DbPropertyExpression property, out object value) { property = null; value = null; // make sure when is of the form Discriminator = Constant if (expression.ExpressionKind != DbExpressionKind.Equals) { return false; } var equals = (DbBinaryExpression)expression; if (equals.Left.ExpressionKind != DbExpressionKind.Property) { return false; } property = (DbPropertyExpression)equals.Left; if (!TryMatchConstant(equals.Right, out value)) { return false; } // verify the property is a property of the input variable if (property.Instance.ExpressionKind != DbExpressionKind.VariableReference || ((DbVariableReferenceExpression)property.Instance).VariableName != propertyVariable) { return false; } return true; }
public override DbExpression Visit(DbPropertyExpression property) { // check for a property of the outer projection binding (that can be remapped) if (property.Instance.ExpressionKind == DbExpressionKind.VariableReference && IsOuterBindingVarRef((DbVariableReferenceExpression)property.Instance)) { return m_varRefMemberBindings[property.Property.Name]; } return base.Visit(property); }
public override DbExpression Visit(DbPropertyExpression expression) { DbExpression result = null; DbExpression replacementValue; if (expression.Instance.ExpressionKind == DbExpressionKind.VariableReference && (((DbVariableReferenceExpression)expression.Instance).VariableName == this.variableName) && this.replacements.TryGetValue(expression.Property.Name, out replacementValue)) { result = replacementValue; } else { result = base.Visit(expression); } return result; }
public override void Visit(DbPropertyExpression expression) { Contract.Requires(expression != null); }
private string GetValue(DbPropertyExpression prop, DbConstantExpression val) { var dbCastExpression = val.CastTo(prop.Property.TypeUsage); var value = dbCastExpression.ToString(); return value; }
/// <summary> /// Helper method for <see cref="RemoveNonSortProperties"/> /// Checks whether expr has a 'match' in the given list of property expressions. /// If it does, the matching expression is removed form the list, to speed up future matching. /// </summary> /// <param name="expr"></param> /// <param name="sortList"></param> /// <param name="exprBindingVariableName"></param> /// <param name="sortExpressionsBindingVariableName"></param> /// <returns></returns> private static bool HasMatchInList( DbPropertyExpression expr, IList<DbPropertyExpression> list, string exprBindingVariableName, string listExpressionsBindingVariableName) { for (var i = 0; i < list.Count; i++) { if (AreMatching(expr, list[i], exprBindingVariableName, listExpressionsBindingVariableName)) { // This method is used for matching element of two list without duplicates, // thus if match is found, remove it from the list, to speed up future matching. list.RemoveAt(i); return true; } } return false; }
public override void Visit(DbPropertyExpression expression) { if (!string.IsNullOrEmpty(PropertyAlias)) { _commandText.Append(PropertyAlias); _commandText.Append("."); } _commandText.Append(GenerateMemberTSql(expression.Property)); }
public override void Visit(DbPropertyExpression expression) { commandText.Append(DmlSqlGenerator.GenerateMemberSql(expression.Property)); }
public override void Visit(DbPropertyExpression propertyExpression) { DebugCheck.NotNull(propertyExpression); _select.Append(_currentTableAlias); _select.Append("."); _select.Append(SqlGenerator.QuoteIdentifier(propertyExpression.Property.Name)); if (!string.IsNullOrWhiteSpace(_nextPropertyAlias) && !string.Equals(_nextPropertyAlias, propertyExpression.Property.Name, StringComparison.Ordinal)) { _select.Append(" AS "); _select.Append(_nextPropertyAlias); } }
/// <summary> /// Visitor pattern method for DbPropertyExpression. /// </summary> /// <param name="expression"> The DbPropertyExpression that is being visited. </param> public abstract void Visit(DbPropertyExpression expression);
/// <summary> /// Visitor pattern method for <see cref="DbPropertyExpression" />. /// </summary> /// <param name="expression"> The DbPropertyExpression that is being visited. </param> /// <exception cref="ArgumentNullException"> /// <paramref name="expression" /> /// is null /// </exception> public override void Visit(DbPropertyExpression expression) { Check.NotNull(expression, "expression"); if (expression.Instance != null) { VisitExpression(expression.Instance); } }
/// <summary> /// Determines whether two expressions match. /// They match if they are of the shape /// expr1 -> DbPropertyExpression(... (DbPropertyExpression(DbVariableReferenceExpression(expr1BindingVariableName), nameX), ..., name1) /// expr1 -> DbPropertyExpression(... (DbPropertyExpression(DbVariableReferenceExpression(expr2BindingVariableName), nameX), ..., name1), /// /// i.e. if they only differ in the name of the binding. /// </summary> /// <param name="expr1"></param> /// <param name="expr2"></param> /// <param name="expr1BindingVariableName"></param> /// <param name="expr2BindingVariableName"></param> /// <returns></returns> private static bool AreMatching( DbPropertyExpression expr1, DbPropertyExpression expr2, string expr1BindingVariableName, string expr2BindingVariableName) { if (expr1.Property.Name != expr2.Property.Name) { return false; } if (expr1.Instance.ExpressionKind != expr2.Instance.ExpressionKind) { return false; } if (expr1.Instance.ExpressionKind == DbExpressionKind.Property) { return AreMatching( (DbPropertyExpression)expr1.Instance, (DbPropertyExpression)expr2.Instance, expr1BindingVariableName, expr2BindingVariableName); } var instance1 = (DbVariableReferenceExpression)expr1.Instance; var instance2 = (DbVariableReferenceExpression)expr2.Instance; return (String.Equals(instance1.VariableName, expr1BindingVariableName, StringComparison.Ordinal) && String.Equals(instance2.VariableName, expr2BindingVariableName, StringComparison.Ordinal)); }
public override void Visit(DbPropertyExpression e) { // // Currently the DbPropertyExpression.EdmProperty member property may only be either: // - EdmProperty // - RelationshipEndMember // - NavigationProperty // Begin(e); RelationshipEndMember end = e.Property as RelationshipEndMember; if (end != null) { Dump(end, "Property"); } else if (Helper.IsNavigationProperty(e.Property)) { Dump((NavigationProperty)e.Property, "Property"); } else { Dump((EdmProperty)e.Property); } if (e.Instance != null) { Dump(e.Instance, "Instance"); } End(e); }
public override void Visit(DbPropertyExpression e) { e.Instance.Accept(this); VisitExprKind(e.ExpressionKind); _key.Append(e.Property.Name); }
public override void Visit(DbPropertyExpression expression) { _commandText.Append(GenerateMemberTSql(expression.Property)); }
/// <summary> /// Visitor pattern method for <see cref="DbPropertyExpression"/>. /// </summary> /// <param name="expression">The DbPropertyExpression that is being visited.</param> /// <exception cref="ArgumentNullException"><paramref name="expression"/> is null</exception> public override void Visit(DbPropertyExpression expression) { if (expression.Instance != null) { VisitExpression(expression.Instance); } }