Ejemplo n.º 1
0
        private SqlStatement VisitDelete(Expression item, LambdaExpression check) {
            if (item == null) {
                throw Error.ArgumentNull("item");
            }

            bool saveAllowDeferred = this.allowDeferred;
            this.allowDeferred = false;

            try {
                MetaTable metaTable = this.services.Model.GetTable(item.Type);
                Expression source = this.services.Context.GetTable(metaTable.RowType.Type).Expression;
                Type rowType = metaTable.RowType.Type;

                // construct identity predicate based on supplied item
                ParameterExpression p = Expression.Parameter(rowType, "p");
                LambdaExpression idPredicate = Expression.Lambda(Expression.Equal(p, item), p);

                // combine predicate and check expression into single find predicate
                LambdaExpression findPredicate = idPredicate;
                if (check != null) {
                    findPredicate = Expression.Lambda(Expression.And(Expression.Invoke(findPredicate, p), Expression.Invoke(check, p)), p);
                }
                Expression seq = Expression.Call(typeof(Enumerable), "Where", new Type[] { rowType }, source, findPredicate);
                SqlSelect ss = new RetypeCheckClause().VisitSelect(this.VisitSequence(seq));
                this.allowDeferred = saveAllowDeferred;

                SqlDelete sd = new SqlDelete(ss, source);
                return sd;
            }
            finally {
                this.allowDeferred = saveAllowDeferred;
            }
        }
Ejemplo n.º 2
0
        private SqlStatement VisitUpdate(Expression item, LambdaExpression check, LambdaExpression resultSelector) {
            if (item == null) {
                throw Error.ArgumentNull("item");
            }
            MetaTable metaTable = this.services.Model.GetTable(item.Type);
            Expression source = this.services.Context.GetTable(metaTable.RowType.Type).Expression;
            Type rowType = metaTable.RowType.Type;

            bool saveAllowDeferred = this.allowDeferred;
            this.allowDeferred = false;

            try {
                Expression seq = source;
                // construct identity predicate based on supplied item
                ParameterExpression p = Expression.Parameter(rowType, "p");
                LambdaExpression idPredicate = Expression.Lambda(Expression.Equal(p, item), p);

                // combine predicate and check expression into single find predicate
                LambdaExpression findPredicate = idPredicate;
                if (check != null) {
                    findPredicate = Expression.Lambda(Expression.And(Expression.Invoke(findPredicate, p), Expression.Invoke(check, p)), p);
                }
                seq = Expression.Call(typeof(Enumerable), "Where", new Type[] { rowType }, seq, findPredicate);

                // source 'query' is based on table + find predicate
                SqlSelect ss = new RetypeCheckClause().VisitSelect(this.VisitSequence(seq));

                // construct update assignments from 'item' info
                List<SqlAssign> assignments = new List<SqlAssign>();
                ConstantExpression conItem = item as ConstantExpression;
                if (conItem == null) {
                    throw Error.UpdateItemMustBeConstant();
                }
                if (conItem.Value == null) {
                    throw Error.ArgumentNull("item");
                }
                // get changes from data services to construct update command
                Type entityType = conItem.Value.GetType();
                MetaType metaType = this.services.Model.GetMetaType(entityType);
                ITable table = this.services.Context.GetTable(metaType.InheritanceRoot.Type);
                foreach (ModifiedMemberInfo mmi in table.GetModifiedMembers(conItem.Value)) {
                    MetaDataMember mdm = metaType.GetDataMember(mmi.Member);
                    assignments.Add(
                        new SqlAssign(
                            sql.Member(ss.Selection, mmi.Member),
                            new SqlValue(mdm.Type, this.typeProvider.From(mdm.Type), mmi.CurrentValue, true, source),
                            source
                            ));
                }

                SqlUpdate upd = new SqlUpdate(ss, assignments, source);

                if (resultSelector == null) {
                    return upd;
                }

                SqlSelect select = null;

                // build select to return result
                seq = source;
                seq = Expression.Call(typeof(Enumerable), "Where", new Type[] { rowType }, seq, idPredicate);
                seq = Expression.Call(typeof(Enumerable), "Select", new Type[] { rowType, resultSelector.Body.Type }, seq, resultSelector);
                select = this.VisitSequence(seq);
                select.Where = sql.AndAccumulate(
                    sql.Binary(SqlNodeType.GT, this.GetRowCountExpression(), sql.ValueFromObject(0, false, this.dominatingExpression)),
                    select.Where    
                    );

                // combine update & select into statement block
                SqlBlock block = new SqlBlock(source);
                block.Statements.Add(upd);
                block.Statements.Add(select);
                return block;
            }
            finally {
                this.allowDeferred = saveAllowDeferred;
            }
        }