public override EntityExpression IncludeMembers(EntityExpression entity, Func <MemberInfo, bool> fnIsIncluded) { var assignments = this.GetAssignments(entity.Expression).ToDictionary(ma => ma.Member.Name); bool anyAdded = false; foreach (var mi in this.mapping.GetMappedMembers(entity.Entity)) { EntityAssignment ea; bool okayToInclude = !assignments.TryGetValue(mi.Name, out ea) || IsNullRelationshipAssignment(entity.Entity, ea); if (okayToInclude && fnIsIncluded(mi)) { ea = new EntityAssignment(mi, this.GetMemberExpression(entity.Expression, entity.Entity, mi)); assignments[mi.Name] = ea; anyAdded = true; } } if (anyAdded) { return(new EntityExpression(entity.Entity, this.BuildEntityExpression(entity.Entity, assignments.Values.ToList()))); } return(entity); }
protected override Expression VisitEntity(EntityExpression entity) { return(this.Visit(entity.Expression)); }
/// <summary> /// </summary> /// <returns></returns> public abstract bool HasIncludedMembers(EntityExpression entity);
/// <summary> /// Recreate the type projection with the additional members included /// </summary> /// <param name="entity"></param> /// <param name="fnIsIncluded"></param> /// <returns></returns> public abstract EntityExpression IncludeMembers(EntityExpression entity, Func <MemberInfo, bool> fnIsIncluded);
protected virtual bool CompareEntity(EntityExpression x, EntityExpression y) { return(x.Entity == y.Entity && this.Compare(x.Expression, y.Expression)); }
protected Expression Compare(BinaryExpression bop) { var e1 = this.SkipConvert(bop.Left); var e2 = this.SkipConvert(bop.Right); OuterJoinedExpression oj1 = e1 as OuterJoinedExpression; OuterJoinedExpression oj2 = e2 as OuterJoinedExpression; EntityExpression entity1 = oj1 != null ? oj1.Expression as EntityExpression : e1 as EntityExpression; EntityExpression entity2 = oj2 != null ? oj2.Expression as EntityExpression : e2 as EntityExpression; bool negate = bop.NodeType == ExpressionType.NotEqual; // check for outer-joined entity comparing against null. These are special because outer joins have // a test expression specifically desgined to be tested against null to determine if the joined side exists. if (oj1 != null && e2.NodeType == ExpressionType.Constant && ((ConstantExpression)e2).Value == null) { return(MakeIsNull(oj1.Test, negate)); } else if (oj2 != null && e1.NodeType == ExpressionType.Constant && ((ConstantExpression)e1).Value == null) { return(MakeIsNull(oj2.Test, negate)); } // if either side is an entity construction expression then compare using its primary key members if (entity1 != null) { return(this.MakePredicate(e1, e2, this.mapping.GetPrimaryKeyMembers(entity1.Entity), negate)); } else if (entity2 != null) { return(this.MakePredicate(e1, e2, this.mapping.GetPrimaryKeyMembers(entity2.Entity), negate)); } // check for comparison of user constructed type projections var dm1 = this.GetDefinedMembers(e1); var dm2 = this.GetDefinedMembers(e2); if (dm1 == null && dm2 == null) { // neither are constructed types return(bop); } if (dm1 != null && dm2 != null) { // both are constructed types, so they'd better have the same members declared HashSet <string> names1 = new HashSet <string>(dm1.Select(m => m.Name)); HashSet <string> names2 = new HashSet <string>(dm2.Select(m => m.Name)); if (names1.IsSubsetOf(names2) && names2.IsSubsetOf(names1)) { return(MakePredicate(e1, e2, dm1, negate)); } } else if (dm1 != null) { return(MakePredicate(e1, e2, dm1, negate)); } else if (dm2 != null) { return(MakePredicate(e1, e2, dm2, negate)); } throw new InvalidOperationException("Cannot compare two constructed types with different sets of members assigned."); }
protected virtual Expression VisitEntity(EntityExpression entity) { this.Visit(entity.Expression); return(entity); }
protected virtual Expression VisitEntity(EntityExpression entity) { var exp = this.Visit(entity.Expression); return(this.UpdateEntity(entity, exp)); }