예제 #1
0
        internal static SqlCommand BuildEntitySetQuery(EntityQueryContext context, IEntity entity, RelationProperty relationProperty)
        {
            var relationKey = RelationshipUnity.GetRelationship(relationProperty);

            if (relationKey == null || relationKey.Style != RelationshipStyle.One2Many)
            {
                return(null);
            }

            var query = new EntityQueryBuilder(context, relationProperty.RelationType)
                        .Select().All().From();

            var valid = true;

            foreach (var key in relationKey.Keys)
            {
                var val = entity.InternalGetValue(key.ThisProperty);
                if (PropertyValue.IsNullOrEmpty(val) || !val.IsValid)
                {
                    valid = false;
                    continue;
                }

                query = query.And(key.OtherProperty, entity.InternalGetValue(key.ThisProperty));
            }

            if (!valid)
            {
                return(string.Empty);
            }

            return(query.ToSqlCommand());
        }
예제 #2
0
        /// <summary>
        /// 根据关系属性构造查询表达式。
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="relationProperty"></param>
        /// <param name="thisKey"></param>
        /// <param name="otherKey"></param>
        /// <returns></returns>
        protected virtual Expression BuildRelationExpression(IEntity entity, RelationProperty relationProperty, Func <RelationshipKey, IProperty> thisKey, Func <RelationshipKey, IProperty> otherKey)
        {
            var relationKey = RelationshipUnity.GetRelationship(relationProperty);

            if (relationKey == null)
            {
                return(null);
            }

            var        parExp = Expression.Parameter(relationProperty.RelationType, "s");
            Expression binExp = null;

            foreach (var key in relationKey.Keys)
            {
                var val = entity.InternalGetValue(thisKey(key));
                if (PropertyValue.IsNullOrEmpty(val) || !val.IsValid)
                {
                    continue;
                }

                var member = otherKey(key).Info.ReflectionInfo;
                var mbrExp = Expression.MakeMemberAccess(parExp, member);
                var exp    = Expression.Equal(mbrExp, Expression.Constant(val.GetStorageValue()));
                binExp = binExp == null ? exp : Expression.And(binExp, exp);
            }

            if (binExp == null)
            {
                return(null);
            }

            return(Expression.Lambda(binExp, parExp));
        }
예제 #3
0
        internal static Expression GetMemberExpression(Expression root, IProperty property)
        {
            var relationProprety = property as RelationProperty;

            if (relationProprety != null)
            {
                //所关联的实体类型
                var relMetadata = EntityMetadataUnity.GetEntityMetadata(relationProprety.RelationType);
                var projection  = GetTableQuery(relMetadata);

                Expression parentExp = null, childExp = null;
                var        ship = RelationshipUnity.GetRelationship(relationProprety);
                if (ship.ThisType != relationProprety.EntityType)
                {
                    parentExp = projection.Projector;
                    childExp  = root;
                }
                else
                {
                    parentExp = root;
                    childExp  = projection.Projector;
                }

                Expression where = null;
                for (int i = 0, n = ship.Keys.Count; i < n; i++)
                {
                    var equal = GetMemberExpression(parentExp, ship.Keys[i].ThisProperty)
                                .Equal(GetMemberExpression(childExp, ship.Keys[i].OtherProperty));
                    where = (where != null) ? Expression.And(where, equal) : equal;
                }

                var newAlias = new TableAlias();
                var pc       = ColumnProjector.ProjectColumns(CanBeColumnExpression, projection.Projector, null, newAlias, projection.Select.Alias);

                var aggregator = GetAggregator(property.Type, typeof(IEnumerable <>).MakeGenericType(pc.Projector.Type));
                var result     = new ProjectionExpression(
                    new SelectExpression(newAlias, pc.Columns, projection.Select, where),
                    pc.Projector, aggregator
                    );

                return(ApplyPolicy(result, property.Info.ReflectionInfo));
            }

            var table = root as TableExpression;

            if (table != null)
            {
                var sqProperty = property as SubqueryProperty;
                if (sqProperty != null)
                {
                    return(new SubqueryColumnExpression(property.Type, table.Alias, property.Info.FieldName, sqProperty.Subquery));
                }
                else if (property is ISavedProperty)
                {
                    return(new ColumnExpression(property.Type, table.Alias, property.Name, property.Info));
                }
            }
            return(QueryBinder.BindMember(root, property.Info.ReflectionInfo));
        }
예제 #4
0
        /// <summary>
        /// 处理关联的实体集合。
        /// </summary>
        /// <param name="queryable"></param>
        /// <param name="entity"></param>
        /// <param name="entitySet"></param>
        /// <param name="property"></param>
        private void HandleRelationEntitySet(IQueryable queryable, IEntity entity, IEntitySet entitySet, IProperty property)
        {
            var list     = (IEntitySetInternalExtension)entitySet;
            var added    = list.GetAttachedList();
            var modified = list.GetModifiedList();
            var deleted  = list.GetDetachedList();

            if (deleted.Count() > 0)
            {
                queryable.BatchOperate(deleted, queryable.CreateDeleteExpression(true));
            }

            if (modified.Count() > 0)
            {
                if (entitySet.AllowBatchUpdate)
                {
                    queryable.BatchOperate(modified, queryable.CreateUpdateExpression());
                }
                else
                {
                    foreach (var e in modified)
                    {
                        queryable.UpdateEntity(e);
                        e.SetState(EntityState.Unchanged);
                        HandleRelationProperties(e);
                    }
                }
            }

            if (added.Count() > 0)
            {
                var relation = RelationshipUnity.GetRelationship(property);
                added.ForEach(e =>
                {
                    foreach (var key in relation.Keys)
                    {
                        var value = entity.InternalGetValue(key.ThisProperty);
                        e.InternalSetValue(key.OtherProperty, value);
                    }
                });

                if (entitySet.AllowBatchInsert)
                {
                    queryable.BatchOperate(added, queryable.CreateInsertExpression());
                }
                else
                {
                    foreach (var e in added)
                    {
                        queryable.CreateEntity(e);
                        e.SetState(EntityState.Unchanged);
                        HandleRelationProperties(e);
                    }
                }
            }

            list.Reset();
        }
예제 #5
0
        internal static Expression GetMemberExpression(TranslateContext transContext, Expression root, IProperty property)
        {
            if (property is RelationProperty relationProprety)
            {
                //所关联的实体类型
                var relMetadata = EntityMetadataUnity.GetEntityMetadata(relationProprety.RelationalType);
                var projection  = GetTableQuery(transContext, relMetadata, false, false);

                Expression parentExp = null, childExp = null;
                var        ship = RelationshipUnity.GetRelationship(relationProprety);

                if (ship.ThisType != relationProprety.EntityType)
                {
                    parentExp = projection.Projector;
                    childExp  = root;
                }
                else
                {
                    parentExp = root;
                    childExp  = projection.Projector;
                }

                var where = ship.Keys.Select(r =>
                                             GetMemberExpression(transContext, parentExp, r.ThisProperty).Equal(GetMemberExpression(transContext, childExp, r.OtherProperty)))
                            .Aggregate(Expression.And);

                var newAlias = new TableAlias();
                var pc       = ColumnProjector.ProjectColumns(CanBeColumnExpression, projection.Projector, null, newAlias, projection.Select.Alias);

                var aggregator = GetAggregator(property.Type, typeof(IEnumerable <>).MakeGenericType(pc.Projector.Type));
                var result     = new ProjectionExpression(
                    new SelectExpression(newAlias, pc.Columns, projection.Select, where),
                    pc.Projector, aggregator, projection.IsAsync, projection.IsNoTracking
                    );

                return(transContext.QueryPolicy.ApplyPolicy(result, property.Info.ReflectionInfo, ex => QueryBinder.Bind(transContext, ex)));
            }

            if (root is TableExpression table)
            {
                if (property is SubqueryProperty sqProperty)
                {
                    return(new SubqueryColumnExpression(property.Type, table.Alias, property.Info.FieldName, sqProperty.Subquery));
                }
                else if (property is ISavedProperty)
                {
                    return(new ColumnExpression(property.Type, table.Alias, property.Name, property.Info));
                }
            }

            return(QueryBinder.BindMember(root, property.Info.ReflectionInfo));
        }
예제 #6
0
        internal static SqlCommand BuildReferenceQuery(EntityQueryContext context, IEntity entity, ReferenceProperty referenceProperty)
        {
            var relationKey = RelationshipUnity.GetRelationship(referenceProperty);

            if (relationKey == null)
            {
                return(null);
            }
            var query = new EntityQueryBuilder(context, referenceProperty.RelationType)
                        .Select().Single(referenceProperty.Reference).From();

            foreach (var key in relationKey.Keys)
            {
                query = query.And(key.ThisProperty, entity.InternalGetValue(key.OtherProperty));
            }
            return(query.ToSqlCommand());
        }
예제 #7
0
        internal static SqlCommand BuildEntityQuery(EntityQueryContext context, IEntity entity, RelationProperty relationProperty)
        {
            var relationKey = RelationshipUnity.GetRelationship(relationProperty);

            if (relationKey == null)
            {
                return(null);
            }

            Type relationType;
            Func <RelationshipKey, IProperty> func1, func2;

            if (entity.EntityType == relationKey.ThisType)
            {
                relationType = relationKey.OtherType;
                func1        = key => key.OtherProperty;
                func2        = key => key.ThisProperty;
            }
            else
            {
                relationType = relationKey.ThisType;
                func1        = key => key.ThisProperty;
                func2        = key => key.OtherProperty;
            }

            var query = new EntityQueryBuilder(context, relationType)
                        .Select().All().From();

            foreach (var key in relationKey.Keys)
            {
                var val = entity.InternalGetValue(func2(key));
                if (PropertyValue.IsNullOrEmpty(val) || !val.IsValid)
                {
                    return(string.Empty);
                }
                query = query.And(func1(key), val);
            }
            return(query.ToSqlCommand());
        }