示例#1
0
 public override bool IsEqualTo(TableExpression expression)
 {
     SubSelectExpression subSelectTable = expression as SubSelectExpression;
     if (subSelectTable == null)
         return false;
     return Name == expression.Name && JoinID == expression.JoinID && Select == subSelectTable.Select;
 }
示例#2
0
 public ColumnExpression(TableExpression table, DbColumnInfo columnInfo)
     : base(SqlExpressionType.Column, GetMemberType(columnInfo))
 {
     Table = table;
     ColumnInfo = columnInfo;
     Name = ColumnInfo.ColumnName;
 }
示例#3
0
 public NonQueryLinqCommandData(LinqCommand baseLinqCommand, SelectExpression baseSelect, TableExpression targetTable, bool isSingleTable)
 {
     BaseLinqCommand = baseLinqCommand;
       BaseSelect = baseSelect;
       TargetTable = targetTable;
       IsSingleTableCommand = isSingleTable;
 }
示例#4
0
 /// <summary>
 /// Set table join
 /// </summary>
 /// <param name="joinType"></param>
 /// <param name="joinedTable"></param>
 /// <param name="joinExpression"></param>
 public void Join(TableJoinType joinType, TableExpression joinedTable, Expression joinExpression)
 {
     //RI: special case - inner joins on top of outer joins should become outer joins as well
       if (joinedTable.JoinedTable != null && (joinedTable.JoinType & TableJoinType.FullOuter) != 0)
     joinType |= joinedTable.JoinType;
       JoinExpression = joinExpression;
       JoinType = joinType;
       JoinedTable = joinedTable;
 }
示例#5
0
 public virtual bool IsEqualTo(TableExpression table)
 {
     return Name == table.Name && JoinID == table.JoinID && this.Alias == table.Alias; //RI: added Alias comparison
 }
 /// <summary>
 /// Registers a column
 /// This method requires the table to be already registered
 /// </summary>
 /// <param name="table"></param>
 /// <param name="name"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 public ColumnExpression RegisterColumn(TableExpression table, string name, TranslationContext context)
 {
     var queryColumn = GetRegisteredColumn(table, name, context);
     if (queryColumn == null)
     {
     table = RegisterTable(table, context);
     queryColumn = CreateColumn(table, name, context);
     context.CurrentSelect.Columns.Add(queryColumn);
     }
     return queryColumn;
 }
示例#7
0
 public override Expression Mutate(System.Collections.Generic.IList<Expression> newOperands)
 {
     if (newOperands != null && newOperands.Count > 0)
     Table = (TableExpression) newOperands[0];
       return this;
 }
示例#8
0
 public override string GetTable(TableExpression tableExpression)
 {
     var options = tableExpression.LockOptions;
       string hint = null;
       if (options.IsSet(LockOptions.ForUpdate))
     hint = "UpdLock";
     // hint = "RepeatableRead, RowLock";
       else if (options.IsSet(LockOptions.SharedRead))
     hint = null; // "Serializable"; //turns out we do not need any hint here if we run in Snapshot level
     // hint = "RepeatableRead, RowLock";
       else if (options.IsSet(LockOptions.NoLock))
     hint = "NOLOCK";
       var table = base.GetTable(tableExpression);
       //Note: for MS SQL, table alias (if present) goes before the hint ( ... FROM Tbl t WITH(NOLOCK) ...), so it works as coded
       if (hint!=null)
     table += " WITH(" + hint + ")";
       return table;
 }
示例#9
0
 public virtual bool IsEqualTo(TableExpression table)
 {
     return(Name == table.Name && JoinID == table.JoinID && this.Alias == table.Alias); //RI: added Alias comparison
 }
 private Expression BuildListPropertyJoinExpression(TableExpression fromTable, TableExpression toTable, EntityMemberInfo refMember, TranslationContext context)
 {
     var fromKeyMembers = refMember.ReferenceInfo.FromKey.ExpandedKeyMembers;
       var toKeyMembers = refMember.ReferenceInfo.ToKey.ExpandedKeyMembers;
       var clauses = new List<Expression>();
       for (int i = 0; i < fromKeyMembers.Count; i++) {
     var mFrom = fromKeyMembers[i];
     var mTo = toKeyMembers[i];
     var colFrom = RegisterColumn(fromTable, mFrom.Member.ClrClassMemberInfo, context);
     var colTo = RegisterColumn(toTable, mTo.Member.ClrClassMemberInfo, context);
     var eqExpr = MakeEqual(colFrom, colTo);
     clauses.Add(eqExpr);
       }
       //Build AND
       var result = clauses[0];
       for (int i = 1; i < clauses.Count; i++)
     result = Expression.And(result, clauses[i]);
       return result;
 }
        /// <summary>
        /// Promotes a table to a common parent between its current scope and our current scope
        /// </summary>
        /// <param name="tableExpression"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        protected virtual TableExpression PromoteTable(TableExpression tableExpression, TranslationContext context)
        {
            int currentIndex = 0;
            SelectExpression oldSelect = null;
            SelectExpression commonScope = null;
            TableExpression foundTable = null;
            do
            {
            // take a select
            oldSelect = context.SelectExpressions[currentIndex];

            // look for a common scope
            if (oldSelect != context.CurrentSelect)
            {
                commonScope = FindCommonScope(oldSelect, context.CurrentSelect);
                if (commonScope != null)
                    // if a common scope exists, look for an equivalent table in that select
                    for (int tableIndex = 0; tableIndex < oldSelect.Tables.Count && foundTable == null; tableIndex++)
                    {
                        if (oldSelect.Tables[tableIndex].IsEqualTo(tableExpression))
                        {
                            // found a matching table!
                            foundTable = oldSelect.Tables[tableIndex];
                        }
                    }
            }
            ++currentIndex;
            }
            while (currentIndex < context.SelectExpressions.Count && foundTable == null);

            if (foundTable != null)
            {
            oldSelect.Tables.Remove(foundTable);
            commonScope.Tables.Add(foundTable);
            }
            return foundTable;
        }
 /// <summary>
 /// Returns a registered column, or null if not found
 /// This method requires the table to be already registered
 /// </summary>
 /// <param name="table"></param>
 /// <param name="name"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 protected virtual ColumnExpression GetRegisteredColumn(TableExpression table, string name,
     TranslationContext context)
 {
     return
     (from queryColumn in context.EnumerateScopeColumns()
       where queryColumn.Table.IsEqualTo(table) && queryColumn.Name == name
       // where queryColumn.Table == table && queryColumn.Name == name // - RI: this does not work
       select queryColumn).SingleOrDefault();
 }
 // RI: new stuff, optimized entity reader
 protected virtual Expression GetOutputTableReader(TableExpression tableExpression,
     ParameterExpression dataRecordParameter, ParameterExpression sessionParameter,
     TranslationContext context)
 {
     // Note: we have to create materializer each time, because column indexes in output can change from query to query
       var entMatzer = new EntityMaterializer(tableExpression.TableInfo);
       var allColExprs = RegisterAllColumns(tableExpression, context);
       foreach (var col in allColExprs) {
     var colIndex = RegisterOutputValue(col, context);
     entMatzer.AddColumn(col.ColumnInfo, colIndex);
       }
       var entMatzerConst = Expression.Constant(entMatzer);
       var callReadEntity = Expression.Call(entMatzerConst, EntityMaterializer.ReadMethodInfo, dataRecordParameter, sessionParameter);
       var convExpr = Expression.Convert(callReadEntity, tableExpression.Type);
       return convExpr;
 }
 public ColumnExpression CreateColumn(TableExpression table, string memberName, TranslationContext context)
 {
     var col = table.TableInfo.GetColumnByMemberName(memberName);
     Util.Check(col != null, "Column for member [{0}] not found in table {1}. Member type is not supported by LINQ.", memberName, table.Name);
     return new ColumnExpression(table, col);
 }
 /// <summary>
 /// Returns an existing table or registers the current one
 /// </summary>
 /// <param name="tableExpression"></param>
 /// <param name="context"></param>
 /// <returns>A registered table or the current newly registered one</returns>
 public virtual TableExpression RegisterTable(TableExpression tableExpression, TranslationContext context)
 {
     // 1. Find the table in current scope
     var foundTableExpression = (from t in context.EnumerateScopeTables()
                             where t.IsEqualTo(tableExpression)
                             select t).FirstOrDefault();
     if (foundTableExpression != null)
     return foundTableExpression;
     // 2. Find it in all scopes, and promote it to current scope.
     foundTableExpression = PromoteTable(tableExpression, context);
     if (foundTableExpression != null)
     return foundTableExpression;
     // 3. Add it
     context.CurrentSelect.Tables.Add(tableExpression);
     return tableExpression;
 }
 public ColumnExpression RegisterColumn(TableExpression tableExpression, MemberInfo memberInfo, TranslationContext context)
 {
     return RegisterColumn(tableExpression, memberInfo.Name, context);
 }
示例#17
0
 public ColumnExpression(TableExpression table, DbColumnInfo columnInfo) : base(SqlExpressionType.Column, GetMemberType(columnInfo))
 {
     Table      = table;
     ColumnInfo = columnInfo;
     Name       = ColumnInfo.ColumnName;
 }
        private Expression AnalyzeEntityListMember(TableExpression table, PropertyInfo property, TranslationContext context)
        {
            var propType = property.PropertyType;
            if (!propType.IsEntitySequence())
              return null;
            var modelInfo = context.DbModel.EntityApp.Model;
            var masterEntInfo = modelInfo.GetEntityInfo(table.Type);
            var entMember = masterEntInfo.GetMember(property.Name);
            Util.Check(entMember != null, "Failed to find member {0} on entity {1}.", property.Name, masterEntInfo.Name);
            Util.Check(entMember.Kind == MemberKind.EntityList, "Internal LINQ error: expected List member ({0}.{1}", masterEntInfo.Name, property.Name);
            var listInfo = entMember.ChildListInfo;
            Expression whereExpr;
            switch(listInfo.RelationType) {

              case EntityRelationType.ManyToOne:
            var childTable = CreateTable(listInfo.TargetEntity.EntityType, context);
            whereExpr = BuildListPropertyJoinExpression(childTable, table, listInfo.ParentRefMember, context);
            if (!string.IsNullOrWhiteSpace(listInfo.Filter)) {
              var filterExpr = new TableFilterExpression(childTable, listInfo.Filter);
              whereExpr = Expression.And(whereExpr, filterExpr);
            }
            context.CurrentSelect.Where.Add(whereExpr);
            return childTable;

              case EntityRelationType.ManyToMany:
            var linkTable = CreateTable(listInfo.LinkEntity.EntityType, context);
            whereExpr = BuildListPropertyJoinExpression(linkTable, table, listInfo.ParentRefMember, context);
            context.CurrentSelect.Where.Add(whereExpr);
            var targetTable = RegisterAssociation(linkTable, listInfo.OtherEntityRefMember, context);
            return targetTable;
            }
            return null; //never happens
        }
 private IList<MemberInfo> GetAssociationMembers(TableExpression thisTableExpression, EntityMemberInfo member,
     out IList<MemberInfo> otherKey, out TableJoinType joinType, out string joinID)
 {
     switch(member.Kind) {
       case MemberKind.EntityRef:
     // by default, join is inner
     joinType = TableJoinType.Inner;
     joinID = member.MemberName;
     var otherType = member.ReferenceInfo.ToKey.Entity.ClassInfo.Type;
     otherKey = member.ReferenceInfo.ToKey.ExpandedKeyMembers.Select(km => (MemberInfo) km.Member.ClrClassMemberInfo).ToList();
     var thisKey = member.ReferenceInfo.FromKey.ExpandedKeyMembers.Select(km => (MemberInfo)km.Member.ClrClassMemberInfo).ToList();
     if(member.Flags.IsSet(EntityMemberFlags.Nullable))
       joinType |= TableJoinType.LeftOuter;
     return thisKey;
       case MemberKind.Transient:
     if(!member.Flags.IsSet(EntityMemberFlags.FromOneToOneRef))
       break;
     joinType = TableJoinType.LeftOuter;
     joinID = member.MemberName;
     var targetEnt = this._dbModel.EntityApp.Model.GetEntityInfo(member.DataType, throwIfNotFound: true);
     otherKey = targetEnt.PrimaryKey.ExpandedKeyMembers.Select(km => km.Member.ClrClassMemberInfo).ToList();
     var thisPk = member.Entity.PrimaryKey.ExpandedKeyMembers.Select(km => km.Member.ClrClassMemberInfo).ToList();
     return thisPk;
     }
     Util.Throw("Cannot create JOIN expression for property {0}, property not supported in LINQ.", member);
     otherKey = null;
     joinType = TableJoinType.Default;
     joinID = null;
     return null;
 }
 public virtual TableExpression CreateTable(Type tableType, TranslationContext context, LockOptions lockOptions = LockOptions.None)
 {
     var tableInfo = _dbModel.GetTable(tableType);
       var tableExpr = new TableExpression(tableType, tableInfo.FullName, tableInfo, lockOptions);
       return tableExpr;
 }
 /// <summary>
 /// Registers all columns of a table.
 /// </summary>
 /// <param name="tableExpression"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 public virtual IList<ColumnExpression> RegisterAllColumns(TableExpression tableExpression, TranslationContext context)
 {
     var result = new List<ColumnExpression>();
       foreach (var colInfo in tableExpression.TableInfo.Columns)
       {
     if (colInfo.Member == null)
       continue;
     var colExpr = RegisterColumn(tableExpression, colInfo.Member.MemberName, context);
     result.Add(colExpr);
       }
       return result;
 }
示例#22
0
 /// <summary>
 /// Set table join
 /// </summary>
 /// <param name="joinType"></param>
 /// <param name="joinedTable"></param>
 /// <param name="joinExpression"></param>
 /// <param name="joinID"></param>
 public void Join(TableJoinType joinType, TableExpression joinedTable, Expression joinExpression, string joinID)
 {
     Join(joinType, joinedTable, joinExpression);
     JoinID = joinID;
 }
示例#23
0
 public virtual string GetTable(TableExpression tableExpr)
 {
     var result = GetSafeName(tableExpr.Name);
       if (!string.IsNullOrWhiteSpace(tableExpr.Alias))
     result += " " + GetTableAlias(tableExpr.Alias);
       return result;
 }
示例#24
0
 public TableFilterExpression(TableExpression table, string filter)
     : base(SqlExpressionType.TableFilter, typeof(bool))
 {
     Table = table;
       Filter = filter;
 }
示例#25
0
 /// <summary>
 /// Replaces a table selection by a selection of all mapped columns (ColumnExpressions).
 /// ColumnExpressions will be replaced at a later time by the tier splitter
 /// </summary>
 /// <param name="tableExpression"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 protected virtual Expression GetSelectTableExpression(TableExpression tableExpression, TranslationContext context)
 {
     var bindings = new List<MemberBinding>();
     foreach (var columnExpression in RegisterAllColumns(tableExpression, context))
     {
         var binding = Expression.Bind((MethodInfo) columnExpression.ColumnInfo.Member.ClrClassMemberInfo, columnExpression);
         bindings.Add(binding);
     }
     var newExpression = Expression.New(tableExpression.Type);
     return Expression.MemberInit(newExpression, bindings);
 }
示例#26
0
 public TableFilterExpression(TableExpression table, string filter)  : base(SqlExpressionType.TableFilter, typeof(bool))
 {
     Table  = table;
     Filter = filter;
 }
        public virtual TableExpression RegisterAssociation(TableExpression tableExpression, EntityMemberInfo refMember, TranslationContext context)
        {
            IList<MemberInfo> otherKeys;
            TableJoinType joinType;
            string joinID;
            var theseKeys = GetAssociationMembers(tableExpression, refMember, out otherKeys, out joinType, out joinID);
            // if the memberInfo has no corresponding association, we get a null, that we propagate
            if (theseKeys == null)
            return null;

            // the current table has the foreign key, the other table the referenced (usually primary) key
            if (theseKeys.Count != otherKeys.Count)
            Util.Throw("S0128: Association arguments (FK and ref'd PK) don't match");

            // we first create the table, with the JoinID, and we MUST complete the table later, with the Join() method
            var otherType = refMember.DataType;
            var otherTableInfo = context.DbModel.GetTable(otherType);
            var otherTableExpression = CreateTable(otherType, context); // new TableExpression(otherType, otherTableInfo.FullName, otherTableInfo, joinID);
            otherTableExpression = RegisterTable(otherTableExpression, context);
            Expression joinExpression = null;

            var createdColumns = new List<ColumnExpression>();
            for (int keyIndex = 0; keyIndex < theseKeys.Count; keyIndex++)
            {
            // joinedKey is registered, even if unused by final select (required columns will be filtered anyway)
            Expression otherKey = RegisterColumn(otherTableExpression, otherKeys[keyIndex], context);
            // foreign is created, we will store it later if this assocation is registered too
            Expression thisKey = CreateColumn(tableExpression, theseKeys[keyIndex].Name, context);
            createdColumns.Add((ColumnExpression)thisKey);

            // the other key is set as left operand, this must be this way
            // since some vendors (SQL Server) don't support the opposite
            var referenceExpression = MakeEqual(otherKey, thisKey);

            // if we already have a join expression, then we have a double condition here, so "AND" it
            if (joinExpression != null)
                joinExpression = Expression.And(joinExpression, referenceExpression);
            else
                joinExpression = referenceExpression;
            }
            // we complete the table here, now that we have all join information
            otherTableExpression.Join(joinType, tableExpression, joinExpression);

            // our table is created, with the expressions
            // now check if we didn't register exactly the same
            var existingTable = (from t in context.EnumerateScopeTables() where t.IsEqualTo(otherTableExpression) select t).SingleOrDefault();
            if (existingTable != null)
            return existingTable;

            context.CurrentSelect.Tables.Add(otherTableExpression);
            foreach (var createdColumn in createdColumns)
            context.CurrentSelect.Columns.Add(createdColumn);
            return otherTableExpression;
        }
示例#28
0
 /// <summary>
 /// Set table join
 /// </summary>
 /// <param name="joinType"></param>
 /// <param name="joinedTable"></param>
 /// <param name="joinExpression"></param>
 /// <param name="joinID"></param>
 public void Join(TableJoinType joinType, TableExpression joinedTable, Expression joinExpression, string joinID)
 {
     Join(joinType, joinedTable, joinExpression);
     JoinID = joinID;
 }
示例#29
0
 protected virtual bool MustDeclareAsJoin(IList<TableExpression> tables, TableExpression table)
 {
     // Temp hack, trying make all joins
       if(tables.Count == 1 && table == tables[0])
     return false;
       if(table.JoinExpression == null)
     return false;
       return true;
     /*
     // the first table can not be declared as join
     if (table == tables[0])
         return false;
     // we must declare as join, whatever the join is,
     // if some of the registered tables are registered as complex join
     if (tables.Any(t => t.JoinType != TableJoinType.Inner))
         return table.JoinExpression != null;
     return false;
      */
 }