Ejemplo n.º 1
0
        /// <summary>
        /// 构造方法 QueryChildren 的表达式。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="metadata"></param>
        /// <param name="parent"></param>
        /// <param name="predicate"></param>
        /// <param name="recurrence"></param>
        /// <returns></returns>
        internal static Expression BuildQueryChildrenExpression <T>(EntityTreeMetadata metadata, T parent, Expression <Func <T, bool> > predicate, bool recurrence = false) where T : class, IEntity
        {
            var parExp    = Expression.Parameter(typeof(T), "s");
            var memberExp = Expression.MakeMemberAccess(parExp, metadata.InnerSign.Info.ReflectionInfo);
            var no        = parent == null ? string.Empty : (string)parent.GetValue(metadata.InnerSign);

            Expression condition;

            if (recurrence)
            {
                condition = Expression.Call(null, MethodCache.Like, memberExp, Expression.Constant(string.Concat(no, "%")));
            }
            else
            {
                condition = Expression.Call(null, MethodCache.Like, memberExp, Expression.Constant(string.Concat(no, new string('_', metadata.SignLength))));
            }

            if (predicate != null)
            {
                var lambda = GetLambda(predicate);
                if (lambda != null)
                {
                    condition = condition.And(DbExpressionReplacer.Replace(lambda.Body, lambda.Parameters[0], parExp));
                }
            }

            return(Expression.Lambda <Func <T, bool> >(condition, parExp));
        }
Ejemplo n.º 2
0
        private Expression ExecuteProjection(ProjectionExpression projection, bool okayToDefer, string commandText, NamedParameter[] parameters, Expression[] values)
        {
            okayToDefer &= this.receivingMember != null && this.policy.IsDeferLoaded(this.receivingMember);

            var saveScope = this.scope;
            ParameterExpression reader = Expression.Parameter(typeof(FieldReader), "r" + nReaders++);

            this.scope = new Scope(this.scope, reader, projection.Select.Alias, projection.Select.Columns);
            LambdaExpression projector = Expression.Lambda(this.Visit(projection.Projector), reader);

            this.scope = saveScope;

            var queryContext = Expression.New(typeof(UWay.Skynet.Cloud.Data.Common.QueryContext <>).MakeGenericType(projector.Body.Type).GetConstructors().FirstOrDefault(),
                                              Expression.Constant(commandText),
                                              Expression.Constant(parameters),
                                              Expression.NewArrayInit(typeof(object), values),
                                              projector);

            Expression result = Expression.Call(this.executor, "Query", new Type[] { projector.Body.Type }, queryContext);

            if (projection.Aggregator != null)
            {
                // apply aggregator
                result = DbExpressionReplacer.Replace(projection.Aggregator.Body, projection.Aggregator.Parameters[0], result);
            }
            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 构造匹配多个内部编码的表达式。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="metadata"></param>
        /// <param name="predicate"></param>
        /// <param name="innerIds"></param>
        /// <returns></returns>
        internal static Expression BuildGetByInnerIdExpression <T>(EntityTreeMetadata metadata, Expression <Func <T, bool> > predicate, List <string> innerIds)
        {
            var parExp    = Expression.Parameter(typeof(T), "s");
            var memberExp = Expression.MakeMemberAccess(parExp, metadata.InnerSign.Info.ReflectionInfo);

            var expres = new List <Expression>();

            foreach (var innerId in innerIds)
            {
                expres.Add(Expression.Equal(memberExp, Expression.Constant(innerId)));
            }

            Expression condition = null;

            //如果没有父编码,返回不成立的 1=0 表达式
            if (expres.Count == 0)
            {
                condition = Expression.Equal(Expression.Constant(1, typeof(int)), Expression.Constant(0, typeof(int)));
            }
            else
            {
                condition = expres.Aggregate(Expression.Or);
            }

            if (predicate != null)
            {
                var lambda = GetLambda(predicate);
                if (lambda != null)
                {
                    condition = condition.And(DbExpressionReplacer.Replace(lambda.Body, lambda.Parameters[0], parExp));
                }
            }

            return(Expression.Lambda <Func <T, bool> >(condition, parExp));
        }
        private Expression ExecuteProjection(ProjectionExpression projection, bool okayToDefer, QueryCommand command, Expression[] values)
        {
            okayToDefer &= (this.receivingMember != null && this.policy.IsDeferLoaded(this.receivingMember));

            var saveScope = this.scope;
            ParameterExpression reader = Expression.Parameter(typeof(FieldReader), "r" + nReaders++);

            this.scope = new Scope(this.scope, reader, projection.Select.Alias, projection.Select.Columns);
            LambdaExpression projector = Expression.Lambda(this.Visit(projection.Projector), reader);

            this.scope = saveScope;

            var entity = EntityFinder.Find(projection.Projector);

            string methExecute = okayToDefer
                ? "ExecuteDeferred"
                : "Execute";

            // call low-level execute directly on supplied DbQueryProvider
            Expression result = Expression.Call(this.executor, methExecute, new Type[] { projector.Body.Type },
                                                Expression.Constant(command),
                                                projector,
                                                Expression.Constant(entity, typeof(MappingEntity)),
                                                Expression.NewArrayInit(typeof(object), values)
                                                );

            if (projection.Aggregator != null)
            {
                // apply aggregator
                result = DbExpressionReplacer.Replace(projection.Aggregator.Body, projection.Aggregator.Parameters[0], result);
            }
            return(result);
        }
Ejemplo n.º 5
0
        private Expression BuildExecuteEnumerableCommand(ProjectionExpression projection, bool okayToDefer)
        {
            var elementType = projection.IsSingleton ? projection.Type : projection.Type.GetEnumerableElementType();

            var saveScope     = scope;
            var recordWrapper = Expression.Parameter(typeof(IRecordWrapper), $"rw{nReaders}");
            var dataReader    = Expression.Parameter(typeof(IDataReader), $"dr{nReaders}");

            nReaders++;

            scope = new Scope(this.scope, recordWrapper, dataReader, projection.Select.Alias, projection.Select.Columns);

            var method        = MthExecuteEnumerable.MakeGenericMethod(elementType);
            var projector     = this.Visit(projection.Projector);
            var rowMapper     = CreateDataRowWrapper(projection, projector, elementType);
            var rowMapperType = typeof(IDataRowMapper <>).MakeGenericType(elementType);

            scope = saveScope;

            var result = translator(projection.Select);

            Expression plan = Expression.Call(executor, method,
                                              Expression.Constant((SqlCommand)result.QueryText),
                                              Expression.Constant(result.DataSegment, typeof(IDataSegment)),
                                              CreateParameterCollectionExpression(projection.Select),
                                              Expression.Constant(rowMapper, rowMapperType)
                                              );

            if (projection.Aggregator != null)
            {
                plan = DbExpressionReplacer.Replace(projection.Aggregator.Body, projection.Aggregator.Parameters[0], plan);
            }

            return(plan);
        }
Ejemplo n.º 6
0
        internal Expression GetEntityStateTest(IEntityMapping mapping, Expression instance, LambdaExpression updateCheck)
        {
            ProjectionExpression tq = this.GetQueryExpression(mapping);

            Expression where = this.GetIdentityCheck(tq.Select, mapping, instance);
            Expression check = DbExpressionReplacer.Replace(updateCheck.Body, updateCheck.Parameters[0], tq.Projector);

            where = where.And(check);
            return(new ExistsExpression(new SelectExpression(new TableAlias(), null, tq.Select, where)));
        }
Ejemplo n.º 7
0
            protected override Expression <Func <IDatabase, DataRow, T> > BuildExpressionForDataRow()
            {
                lambda = (LambdaExpression)DbExpressionReplacer.Replace(lambda, recordWrapper, Expression.Constant(RecordWrapper, typeof(IRecordWrapper)));
                if (lambda.Parameters.Count == 1 && lambda.Parameters[0].Type != typeof(IDatabase))
                {
                    return(Expression.Lambda <Func <IDatabase, DataRow, T> >(lambda.Body, executor, lambda.Parameters[0]));
                }

                return((Expression <Func <IDatabase, DataRow, T> >)lambda);
            }
Ejemplo n.º 8
0
            protected override Expression <Func <IDatabase, IDataReader, T> > BuildExpressionForDataReader()
            {
                var exp = (LambdaExpression)DbExpressionReplacer.Replace(_expression, _recordWrapper, Expression.Constant(RecordWrapper, typeof(IRecordWrapper)));

                if (exp.Parameters.Count == 1 && exp.Parameters[0].Type != typeof(IDatabase))
                {
                    return(Expression.Lambda <Func <IDatabase, IDataReader, T> >(exp.Body, _executor, exp.Parameters[0]));
                }

                return((Expression <Func <IDatabase, IDataReader, T> >)exp);
            }
Ejemplo n.º 9
0
        public void AssociateWith <TEntity>(Expression <Func <TEntity, IEnumerable> > memberQuery) where TEntity : IEntity
        {
            var rootMember = RootMemberFinder.Find(memberQuery, memberQuery.Parameters[0]);

            if (rootMember != memberQuery.Body)
            {
                var memberParam = Expression.Parameter(rootMember.Type, "root");
                var newBody     = DbExpressionReplacer.Replace(memberQuery.Body, rootMember, memberParam);
                AddOperation(rootMember.Member, Expression.Lambda(newBody, memberParam));
            }
        }
Ejemplo n.º 10
0
        public virtual Expression GetDeleteExpression(IEntityMapping mapping, Expression instance, LambdaExpression deleteCheck)
        {
            TableExpression table = new TableExpression(new TableAlias(), mapping);

            Expression where = null;

            if (instance != null)
            {
                where = this.GetIdentityCheck(table, mapping, instance);
            }

            if (deleteCheck != null)
            {
                Expression row  = this.GetEntityExpression(table, mapping);
                Expression pred = DbExpressionReplacer.Replace(deleteCheck.Body, deleteCheck.Parameters[0], row);
                where = (where != null) ? where.And(pred) : pred;
            }

            bool supportsVersionCheck = false;

            if (mapping.Version != null && instance != null)
            {
                //var versionValue = GetVersionValue(entity, instance);
                //var versionCheck = GetMemberExpression(table, entity, entity.Version).Equal(Expression.Constant(versionValue));
                //where = (where != null) ? where.And(versionCheck) : versionCheck;

                var version          = mapping.Version;
                var versionValue     = GetVersionValue(mapping, instance);
                var versionExp       = Expression.Constant(versionValue, version.MemberType);
                var memberExpression = GetMemberExpression(table, mapping, mapping.Version);
                if (version.MemberType.IsNullable())
                {
                    var versionCheck = versionValue == null ? (Expression)memberExpression.Equal(Expression.Constant(null, version.MemberType))
                        : memberExpression.Equal(versionExp);
                    where = (where != null) ? where.And(versionCheck) : versionCheck;
                }
                else
                {
                    var versionCheck = memberExpression.Equal(versionExp);
                    where = (where != null) ? where.And(versionCheck) : versionCheck;
                }

                supportsVersionCheck = true;
            }

            object o = null;
            var    c = instance as ConstantExpression;

            if (c != null)
            {
                o = c.Value;
            }
            return(new DeleteCommand(table, where, o, supportsVersionCheck));
        }
Ejemplo n.º 11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="projection"></param>
        /// <param name="okayToDefer"></param>
        /// <returns></returns>
        private Expression ExecuteProjection(ProjectionExpression projection, bool okayToDefer)
        {
            okayToDefer &= (this.receivingMember != null && this.policy.IsDeferLoaded(this.receivingMember));

            // parameterize query
            projection = (ProjectionExpression)Parameterizer.Parameterize(projection);

            if (this.scope != null)
            {
                // also convert references to outer alias to named values!  these become SQL parameters too
                projection = (ProjectionExpression)OuterParameterizer.Parameterize(this.scope.Alias, projection);
            }

            var saveScope = this.scope;
            ParameterExpression reader = Expression.Parameter(typeof(DbDataReader), "r" + nReaders++);

            this.scope = new Scope(this.scope, reader, projection.Source.Alias, projection.Source.Columns);
            LambdaExpression projector = Expression.Lambda(this.Visit(projection.Projector), reader);

            this.scope = saveScope;

            string commandText = this.policy.Mapping.Language.Format(projection.Source);
            ReadOnlyCollection <NamedValueExpression> namedValues = NamedValueGatherer.Gather(projection.Source);

            string[]     names  = namedValues.Select(v => v.Name).ToArray();
            Expression[] values = namedValues.Select(v => Expression.Convert(this.Visit(v.Value), typeof(object))).ToArray();

            string methExecute = okayToDefer
                ? "ExecuteDeferred"
                : "Execute";

            if (okayToDefer)
            {
            }

            // call low-level execute directly on supplied DbQueryProvider
            Expression result = Expression.Call(this.provider, methExecute, new Type[] { projector.Body.Type },
                                                Expression.New(
                                                    typeof(QueryCommand <>).MakeGenericType(projector.Body.Type).GetConstructors()[0],
                                                    Expression.Constant(commandText),
                                                    Expression.Constant(names),
                                                    projector
                                                    ),
                                                Expression.NewArrayInit(typeof(object), values)
                                                );

            if (projection.Aggregator != null)
            {
                // apply aggregator
                result = DbExpressionReplacer.Replace(projection.Aggregator.Body, projection.Aggregator.Parameters[0], result);
            }
            return(result);
        }
Ejemplo n.º 12
0
        private Expression BuildExecuteEnumerableCommand(ProjectionExpression projection, bool okayToDefer)
        {
            var elementType = projection.IsSingleton ? projection.Type : ReflectionCache.GetMember("EnumerableElementType", projection.Type, k => k.GetEnumerableElementType());

            var saveScope     = _scope;
            var recordWrapper = Expression.Parameter(typeof(IRecordWrapper), $"rw{_readers}");
            var dataReader    = Expression.Parameter(typeof(IDataReader), $"dr{_readers}");

            _readers++;

            _scope = new Scope(_scope, recordWrapper, dataReader, projection.Select.Alias, projection.Select.Columns);

            var projector = Visit(projection.Projector);
            var rowMapper = CreateDataRowWrapper(projector, elementType);

            _scope = saveScope;

            var result = _translator.Translate(projection.Select);

            Expression plan;

            if (_isAsync)
            {
                var method = ReflectionCache.GetMember("ExecuteEnumerableAsync", elementType, k => MethodCache.DbExecuteEnumerableAsync.MakeGenericMethod(k));
                _cancelToken = Expression.Parameter(typeof(CancellationToken), "token");
                plan         = Expression.Call(_executor, method,
                                               Expression.Constant((SqlCommand)result.QueryText),
                                               Expression.Constant(result.DataSegment, typeof(IDataSegment)),
                                               CreateParameterCollectionExpression(projection.Select),
                                               Expression.Constant(rowMapper),
                                               _cancelToken
                                               );
            }
            else
            {
                var method = ReflectionCache.GetMember("ExecuteEnumerable", elementType, k => MethodCache.DbExecuteEnumerable.MakeGenericMethod(k));
                plan = Expression.Call(_executor, method,
                                       Expression.Constant((SqlCommand)result.QueryText),
                                       Expression.Constant(result.DataSegment, typeof(IDataSegment)),
                                       CreateParameterCollectionExpression(projection.Select),
                                       Expression.Constant(rowMapper)
                                       );
            }

            if (projection.Aggregator != null && (projection.Aggregator.Body as MethodCallExpression).Method.Name != nameof(Queryable.AsQueryable))
            {
                plan = DbExpressionReplacer.Replace(projection.Aggregator.Body, projection.Aggregator.Parameters[0], plan);
            }

            return(plan);
        }
Ejemplo n.º 13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="join"></param>
        /// <returns></returns>
        protected override Expression VisitClientJoin(ClientJoinExpression join)
        {
            // convert client join into a up-front lookup table builder & replace client-join in tree with lookup accessor

            // 1) lookup = query.Select(e => new KVP(key: inner, value: e)).ToLookup(kvp => kvp.Key, kvp => kvp.Value)
            Expression innerKey = MakeJoinKey(join.InnerKey);
            Expression outerKey = MakeJoinKey(join.OuterKey);

            ConstructorInfo      kvpConstructor  = typeof(KeyValuePair <,>).MakeGenericType(innerKey.Type, join.Projection.Projector.Type).GetConstructor(new Type[] { innerKey.Type, join.Projection.Projector.Type });
            Expression           constructKVPair = Expression.New(kvpConstructor, innerKey, join.Projection.Projector);
            ProjectionExpression newProjection   = new ProjectionExpression(join.Projection.Source, constructKVPair);

            int        iLookup   = ++nLookup;
            Expression execution = this.ExecuteProjection(newProjection, false);

            ParameterExpression kvp = Expression.Parameter(constructKVPair.Type, "kvp");

            // filter out nulls
            if (join.Projection.Projector.NodeType == (ExpressionType)DbExpressionType.OuterJoined)
            {
                LambdaExpression pred = Expression.Lambda(
                    Expression.NotEqual(
                        Expression.PropertyOrField(kvp, "Value"),
                        Expression.Constant(null, join.Projection.Projector.Type)
                        ),
                    kvp
                    );
                execution = Expression.Call(typeof(Enumerable), "Where", new Type[] { kvp.Type }, execution, pred);
            }

            // make lookup
            LambdaExpression keySelector     = Expression.Lambda(Expression.PropertyOrField(kvp, "Key"), kvp);
            LambdaExpression elementSelector = Expression.Lambda(Expression.PropertyOrField(kvp, "Value"), kvp);
            Expression       toLookup        = Expression.Call(typeof(Enumerable), "ToLookup", new Type[] { kvp.Type, outerKey.Type, join.Projection.Projector.Type }, execution, keySelector, elementSelector);

            // 2) agg(lookup[outer])
            ParameterExpression lookup   = Expression.Parameter(toLookup.Type, "lookup" + iLookup);
            PropertyInfo        property = lookup.Type.GetProperty("Item");
            Expression          access   = Expression.Call(lookup, property.GetGetMethod(), this.Visit(outerKey));

            if (join.Projection.Aggregator != null)
            {
                // apply aggregator
                access = DbExpressionReplacer.Replace(join.Projection.Aggregator.Body, join.Projection.Aggregator.Parameters[0], access);
            }

            this.variables.Add(lookup);
            this.initializers.Add(toLookup);

            return(access);
        }
Ejemplo n.º 14
0
        protected override Expression VisitClientJoin(ClientJoinExpression join)
        {
            // convert client join into a up-front lookup table builder & replace client-join in tree with lookup accessor

            // 1) lookup = query.Select(e => new KVP(key: inner, value: e)).ToLookup(kvp => kvp.Key, kvp => kvp.Value)
            Expression innerKey = MakeJoinKey(join.InnerKey);
            Expression outerKey = MakeJoinKey(join.OuterKey);

            var                  kvpConstructor  = ReflectionCache.GetMember("KeyValueConstructor", new[] { innerKey.Type, join.Projection.Projector.Type }, pars => typeof(KeyValuePair <,>).MakeGenericType(pars).GetConstructor(pars));
            Expression           constructKVPair = Expression.New(kvpConstructor, innerKey, join.Projection.Projector);
            ProjectionExpression newProjection   = new ProjectionExpression(join.Projection.Select, constructKVPair, _isAsync, join.Projection.IsNoTracking);

            int        iLookup   = ++_lookup;
            Expression execution = ExecuteProjection(newProjection, false);

            ParameterExpression kvp = Expression.Parameter(constructKVPair.Type, "kvp");

            // filter out nulls
            if (join.Projection.Projector.NodeType == (ExpressionType)DbExpressionType.OuterJoined)
            {
                var nullType = ReflectionCache.GetMember("NullableType", join.Projection.Projector.Type, k => k.GetNullableType());
                var pred     = Expression.Lambda(
                    Expression.PropertyOrField(kvp, "Value").NotEqual(Expression.Constant(null, nullType)),
                    kvp
                    );
                execution = Expression.Call(typeof(Enumerable), nameof(Enumerable.Where), new Type[] { kvp.Type }, execution, pred);
            }

            // make lookup
            var keySelector     = Expression.Lambda(Expression.PropertyOrField(kvp, "Key"), kvp);
            var elementSelector = Expression.Lambda(Expression.PropertyOrField(kvp, "Value"), kvp);
            var toLookup        = Expression.Call(typeof(Enumerable), nameof(Enumerable.ToLookup), new Type[] { kvp.Type, outerKey.Type, join.Projection.Projector.Type }, execution, keySelector, elementSelector);

            // 2) agg(lookup[outer])
            var        lookup   = Expression.Parameter(toLookup.Type, $"lookup{iLookup}");
            var        property = lookup.Type.GetProperty("Item");
            Expression access   = Expression.Call(lookup, property.GetGetMethod(), Visit(outerKey));

            if (join.Projection.Aggregator != null)
            {
                // apply aggregator
                access = DbExpressionReplacer.Replace(join.Projection.Aggregator.Body, join.Projection.Aggregator.Parameters[0], access);
            }

            _variables.Add(lookup);
            _initializers.Add(toLookup);

            return(access);
        }
Ejemplo n.º 15
0
        internal Expression GetUpdateResult(IEntityMapping mapping, Expression instance, LambdaExpression selector)
        {
            var tq = this.GetQueryExpression(mapping);

            Expression where = this.GetIdentityCheck(tq.Select, mapping, instance);
            Expression selection = DbExpressionReplacer.Replace(selector.Body, selector.Parameters[0], tq.Projector);
            TableAlias newAlias  = new TableAlias();
            var        pc        = ColumnProjector.ProjectColumns(selection, null, newAlias, tq.Select.Alias);

            return(new ProjectionExpression(
                       new SelectExpression(newAlias, pc.Columns, tq.Select, where),
                       pc.Projector,
                       Aggregator.GetAggregator(selector.Body.Type, typeof(IEnumerable <>).MakeGenericType(selector.Body.Type))
                       ));
        }
Ejemplo n.º 16
0
        public virtual Expression GetInsertResult(IEntityMapping mapping, Expression instance, LambdaExpression selector, Dictionary <MemberInfo, Expression> map)
        {
            var tableAlias = new TableAlias();
            var tex        = new TableExpression(tableAlias, mapping);
            var aggregator = Aggregator.GetAggregator(selector.Body.Type, typeof(IEnumerable <>).MakeGenericType(selector.Body.Type));

            Expression where = null;
            DeclarationCommand genIdCommand = null;
            var generatedIds = mapping.PrimaryKeys.Where(m => m.IsPrimaryKey && m.IsGenerated).ToList();

            if (generatedIds.Count > 0)
            {
                if (map == null || !generatedIds.Any(m => map.ContainsKey(m.Member)))
                {
                    var localMap = new Dictionary <MemberInfo, Expression>();
                    genIdCommand = this.GetGeneratedIdCommand(mapping, generatedIds, localMap);
                    map          = localMap;
                }

                // is this just a retrieval of one generated id member?
                var mex = selector.Body as MemberExpression;
                if (mex != null)
                {
                    var id = mapping.Get(mex.Member);
                    if (id != null && id.IsPrimaryKey && id.IsGenerated)
                    {
                        if (genIdCommand != null)
                        {
                            // just use the select from the genIdCommand
                            return(new ProjectionExpression(
                                       genIdCommand.Source,
                                       new ColumnExpression(mex.Type, genIdCommand.Variables[0].SqlType, genIdCommand.Source.Alias, genIdCommand.Source.Columns[0].Name),
                                       aggregator
                                       ));
                        }
                        else
                        {
                            TableAlias alias   = new TableAlias();
                            var        colType = id.SqlType;
                            return(new ProjectionExpression(
                                       new SelectExpression(alias, new[] { new ColumnDeclaration("", map[mex.Member], colType) }, null, null),
                                       new ColumnExpression(mex.Member.GetMemberType(), colType, alias, ""),
                                       aggregator
                                       ));
                        }
                    }

                    where = generatedIds.Select((m, i) =>
                                                this.GetMemberExpression(tex, mapping, m.Member).Equal(map[m.Member])
                                                ).Aggregate((x, y) => x.And(y));
                }
            }
            else
            {
                where = this.GetIdentityCheck(tex, mapping, instance);
            }

            Expression typeProjector = this.GetEntityExpression(tex, mapping);
            Expression selection     = DbExpressionReplacer.Replace(selector.Body, selector.Parameters[0], typeProjector);
            TableAlias newAlias      = new TableAlias();
            var        pc            = ColumnProjector.ProjectColumns(selection, null, newAlias, tableAlias);
            var        pe            = new ProjectionExpression(
                new SelectExpression(newAlias, pc.Columns, tex, where),
                pc.Projector,
                aggregator
                );

            if (genIdCommand != null)
            {
                return(new BlockCommand(genIdCommand, pe));
            }
            return(pe);
        }
Ejemplo n.º 17
0
        public virtual Expression GetUpdateExpression(IEntityMapping mapping, Expression instance, LambdaExpression updateCheck, LambdaExpression selector, Expression @else)
        {
            var tableAlias = new TableAlias();
            var table      = new TableExpression(tableAlias, mapping);

            var where = this.GetIdentityCheck(table, mapping, instance);
            if (updateCheck != null)
            {
                Expression typeProjector = this.GetEntityExpression(table, mapping);
                Expression pred          = DbExpressionReplacer.Replace(updateCheck.Body, updateCheck.Parameters[0], typeProjector);
                where = where != null ? where.And(pred) : pred;
            }

            var assignments = this.GetColumnAssignments(table, instance, mapping, m => m.IsUpdatable && !m.IsVersion);

            var  version = mapping.Version;
            bool supportsVersionCheck = false;


            if (version != null)
            {
                var versionValue     = GetVersionValue(mapping, instance);
                var versionExp       = Expression.Constant(versionValue, version.MemberType);
                var memberExpression = GetMemberExpression(table, mapping, mapping.Version);
                var versionCheck     = memberExpression.Equal(versionExp);
                where = (where != null) ? where.And(versionCheck) : versionCheck;

                if (version.MemberType.IsNullable())
                {
                    var versionAssignment = new ColumnAssignment(
                        memberExpression as ColumnExpression,
                        versionValue == null ?
                        (Expression)Expression.Constant(1, version.MemberType)
                                                : Expression.Add(memberExpression, Expression.Constant(1, version.MemberType))
                        );
                    assignments.Add(versionAssignment);
                    supportsVersionCheck = true;
                }
                else
                {
                    var versionAssignment = new ColumnAssignment(
                        memberExpression as ColumnExpression,
                        Expression.Add(memberExpression, Expression.Constant(1, version.MemberType))
                        );
                    assignments.Add(versionAssignment);
                    supportsVersionCheck = true;
                }
            }

            object o = null;
            var    c = instance as ConstantExpression;

            if (c != null)
            {
                o = c.Value;
            }
            Expression update = new UpdateCommand(table, where, o, supportsVersionCheck, assignments);

            if (selector != null)
            {
                return(new BlockCommand(
                           update,
                           new IFCommand(
                               this.GetRowsAffectedExpression(update).GreaterThan(Expression.Constant(0)),
                               this.GetUpdateResult(mapping, instance, selector),
                               @else
                               )
                           ));
            }
            else if (@else != null)
            {
                return(new BlockCommand(
                           update,
                           new IFCommand(
                               this.GetRowsAffectedExpression(update).LessThanOrEqual(Expression.Constant(0)),
                               @else,
                               null
                               )
                           ));
            }
            else
            {
                return(update);
            }
        }
Ejemplo n.º 18
0
 protected override Expression <Func <DataRow, T> > BuildExpressionForDataRow()
 {
     expression = DbExpressionReplacer.Replace(expression, recordWrapper, Expression.Constant(RecordWrapper, typeof(IRecordWrapper)));
     return((Expression <Func <DataRow, T> >)expression);
 }