示例#1
0
            static List <IMemberBinder> PrepareMemberBinders(Type type, IDataReader reader, ObjectMemberMapper mapper)
            {
                List <IMemberBinder> memberBinders = new List <IMemberBinder>(reader.FieldCount);

                MemberInfo[]      properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);
                MemberInfo[]      fields     = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetField);
                List <MemberInfo> members    = new List <MemberInfo>(properties.Length + fields.Length);

                members.AddRange(properties);
                members.AddRange(fields);

                TypeDescriptor typeDescriptor = EntityTypeContainer.TryGetDescriptor(type);

                for (int i = 0; i < reader.FieldCount; i++)
                {
                    string     name      = reader.GetName(i);
                    MemberInfo mapMember = TryGetMapMember(members, name, typeDescriptor);

                    if (mapMember == null)
                    {
                        continue;
                    }

                    MRMTuple mMapperTuple = mapper.GetMappingMemberMapper(mapMember);
                    if (mMapperTuple == null)
                    {
                        continue;
                    }

                    PrimitiveMemberBinder memberBinder = new PrimitiveMemberBinder(mapMember, mMapperTuple, i);
                    memberBinders.Add(memberBinder);
                }

                return(memberBinders);
            }
示例#2
0
        string CreateTableScript(Type entityType)
        {
            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entityType);
            string         tableName      = typeDescriptor.Table.Name;

            StringBuilder sb = new StringBuilder();

            sb.AppendLine($"IF NOT EXISTS (select * from sysobjects where name='{tableName}' and xtype='U')");
            sb.Append($"CREATE TABLE {this.QuoteName(tableName)}(");

            string c = "";

            foreach (var propertyDescriptor in typeDescriptor.PrimitivePropertyDescriptors)
            {
                sb.AppendLine(c);
                sb.Append($"  {this.BuildColumnPart(propertyDescriptor)}");
                c = ",";
            }

            if (typeDescriptor.PrimaryKeys.Count > 0)
            {
                string key            = typeDescriptor.PrimaryKeys.First().Column.Name;
                string constraintName = $"PK_{tableName}";
                sb.AppendLine(c);
                sb.Append($"CONSTRAINT {this.QuoteName(constraintName)} PRIMARY KEY CLUSTERED ( {this.QuoteName(key)} ASC )");
            }

            sb.AppendLine();
            sb.Append(");");

            return(sb.ToString());
        }
示例#3
0
        public virtual void TrackEntity(object entity)
        {
            Utils.CheckNull(entity);
            Type entityType = entity.GetType();

            if (ReflectionExtension.IsAnonymousType(entityType))
            {
                return;
            }

            Dictionary <Type, TrackEntityCollection> entityContainer = this.TrackingEntityContainer;

            TrackEntityCollection collection;

            if (!entityContainer.TryGetValue(entityType, out collection))
            {
                TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entityType);

                if (!typeDescriptor.HasPrimaryKey())
                {
                    return;
                }

                collection = new TrackEntityCollection(typeDescriptor);
                entityContainer.Add(entityType, collection);
            }

            collection.TryAddEntity(entity);
        }
示例#4
0
        async Task Save <TEntity>(TEntity entity, TypeDescriptor declaringTypeDescriptor, bool @async)
        {
            await this.Insert(entity, null, @async);

            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity));

            for (int i = 0; i < typeDescriptor.ComplexPropertyDescriptors.Count; i++)
            {
                //entity.TOther
                ComplexPropertyDescriptor navPropertyDescriptor = typeDescriptor.ComplexPropertyDescriptors[i];

                if (declaringTypeDescriptor != null && navPropertyDescriptor.PropertyType == declaringTypeDescriptor.Definition.Type)
                {
                    continue;
                }

                await this.SaveOneToOne(navPropertyDescriptor, entity, typeDescriptor, @async);
            }

            for (int i = 0; i < typeDescriptor.CollectionPropertyDescriptors.Count; i++)
            {
                //entity.List
                CollectionPropertyDescriptor collectionPropertyDescriptor = typeDescriptor.CollectionPropertyDescriptors[i];
                await this.SaveCollection(collectionPropertyDescriptor, entity, typeDescriptor, @async);
            }
        }
示例#5
0
        static async Task <int> Update <TEntity>(IDbContext dbContext, TEntity entity, Expression <Func <TEntity, bool> > condition, bool @async)
        {
            PublicHelper.CheckNull(dbContext);
            PublicHelper.CheckNull(entity);
            PublicHelper.CheckNull(condition);

            Type           entityType     = typeof(TEntity);
            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entityType);

            List <MemberBinding> bindings = new List <MemberBinding>();

            ConstantExpression entityConstantExp = Expression.Constant(entity);

            foreach (PrimitivePropertyDescriptor propertyDescriptor in typeDescriptor.PrimitivePropertyDescriptors)
            {
                if (propertyDescriptor.CannotUpdate())
                {
                    continue;
                }

                Expression       entityMemberAccess = Expression.MakeMemberAccess(entityConstantExp, propertyDescriptor.Property);
                MemberAssignment bind = Expression.Bind(propertyDescriptor.Property, entityMemberAccess);

                bindings.Add(bind);
            }

            return(await UpdateOnly(dbContext, condition, bindings, @async));
        }
        public IObjectActivator CreateObjectActivator(IDbContext dbContext)
        {
            InstanceCreator instanceCreator = this.ConstructorDescriptor.GetInstanceCreator();

            List <IObjectActivator> argumentActivators = this.CreateArgumentActivators(dbContext);
            List <IMemberBinder>    memberBinders      = this.CreateMemberBinders(dbContext);

            IObjectActivator objectActivator;

            if (dbContext != null)
            {
                objectActivator = new ObjectActivatorWithTracking(instanceCreator, argumentActivators, memberBinders, this.CheckNullOrdinal, dbContext);
            }
            else
            {
                objectActivator = new ComplexObjectActivator(instanceCreator, argumentActivators, memberBinders, this.CheckNullOrdinal);
            }

            if (this.IsRoot && this.HasMany())
            {
                TypeDescriptor entityTypeDescriptor          = EntityTypeContainer.GetDescriptor(this.ObjectType);
                List <Tuple <PropertyDescriptor, int> > keys = new List <Tuple <PropertyDescriptor, int> >(entityTypeDescriptor.PrimaryKeys.Count);
                foreach (PrimitivePropertyDescriptor primaryKey in entityTypeDescriptor.PrimaryKeys)
                {
                    keys.Add(new Tuple <PropertyDescriptor, int>(primaryKey, this.PrimitiveMembers[primaryKey.Definition.Property]));
                }

                IEntityRowComparer entityRowComparer = new EntityRowComparer(keys);
                objectActivator = new RootEntityActivator(objectActivator, this.CreateFitter(dbContext), entityRowComparer);
            }

            return(objectActivator);
        }
示例#7
0
        public override int Update <TEntity>(TEntity entity, string table)
        {
            PublicHelper.CheckNull(entity);

            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entity.GetType());

            PublicHelper.EnsureHasPrimaryKey(typeDescriptor);

            Dictionary <PropertyDescriptor, object> keyValueMap = CreateKeyValueMap(typeDescriptor);

            IEntityState entityState = this.TryGetTrackedEntityState(entity);
            Dictionary <PropertyDescriptor, DbExpression> updateColumns = new Dictionary <PropertyDescriptor, DbExpression>();

            foreach (PropertyDescriptor propertyDescriptor in typeDescriptor.PropertyDescriptors)
            {
                if (keyValueMap.ContainsKey(propertyDescriptor))
                {
                    keyValueMap[propertyDescriptor] = propertyDescriptor.GetValue(entity);
                    continue;
                }

                bool hasSequence = propertyDescriptor.HasSequence();
                if (hasSequence)
                {
                    continue;
                }

                object val = propertyDescriptor.GetValue(entity);

                if (entityState != null && !entityState.HasChanged(propertyDescriptor, val))
                {
                    continue;
                }

                DbExpression valExp = DbExpression.Parameter(val, propertyDescriptor.PropertyType, propertyDescriptor.Column.DbType);
                updateColumns.Add(propertyDescriptor, valExp);
            }

            if (updateColumns.Count == 0)
            {
                return(0);
            }

            DbTable            dbTable      = table == null ? typeDescriptor.Table : new DbTable(table, typeDescriptor.Table.Schema);
            DbExpression       conditionExp = MakeCondition(keyValueMap, dbTable);
            DbUpdateExpression e            = new DbUpdateExpression(dbTable, conditionExp);

            foreach (var item in updateColumns)
            {
                e.UpdateColumns.Add(item.Key.Column, item.Value);
            }

            int ret = this.ExecuteSqlCommand(e);

            if (entityState != null)
            {
                entityState.Refresh();
            }
            return(ret);
        }
示例#8
0
        ComplexObjectModel GenComplexObjectModel(ComplexPropertyDescriptor navigationDescriptor, NavigationNode navigationNode, QueryModel queryModel)
        {
            TypeDescriptor navigationTypeDescriptor = EntityTypeContainer.GetDescriptor(navigationDescriptor.PropertyType);

            DbTable           dbTable      = navigationTypeDescriptor.Table;
            DbTableExpression tableExp     = new DbTableExpression(dbTable);
            string            alias        = queryModel.GenerateUniqueTableAlias(dbTable.Name);
            DbTableSegment    joinTableSeg = new DbTableSegment(tableExp, alias, queryModel.FromTable.Table.Lock);

            DbTable            aliasTable            = new DbTable(alias);
            ComplexObjectModel navigationObjectModel = navigationTypeDescriptor.GenObjectModel(aliasTable);

            navigationObjectModel.NullChecking = navigationObjectModel.PrimaryKey;

            PrimitivePropertyDescriptor foreignKeyPropertyDescriptor = navigationDescriptor.ForeignKeyProperty;
            DbExpression          foreignKeyColumn = this.GetPrimitiveMember(foreignKeyPropertyDescriptor.Property);
            DbExpression          joinCondition    = DbExpression.Equal(foreignKeyColumn, navigationObjectModel.PrimaryKey);
            DbJoinTableExpression joinTableExp     = new DbJoinTableExpression(foreignKeyPropertyDescriptor.IsNullable ? DbJoinType.LeftJoin : DbJoinType.InnerJoin, joinTableSeg, joinCondition);

            this.DependentTable.JoinTables.Add(joinTableExp);

            navigationObjectModel.DependentTable = joinTableExp;

            DbExpression condition = this.ParseCondition(navigationNode.Condition, navigationObjectModel, queryModel.ScopeTables);

            //AndWhere的条件放到join条件里去
            joinTableExp.AppendCondition(condition);

            navigationObjectModel.Filter = this.ParseCondition(navigationNode.Filter, navigationObjectModel, queryModel.ScopeTables);

            //queryModel.Filters.Add(navigationObjectModel.Filter);

            return(navigationObjectModel);
        }
示例#9
0
        public override int Delete <TEntity>(TEntity entity, string table)
        {
            PublicHelper.CheckNull(entity);

            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity));

            PublicHelper.EnsureHasPrimaryKey(typeDescriptor);

            Dictionary <PropertyDescriptor, object> keyValueMap = new Dictionary <PropertyDescriptor, object>(typeDescriptor.PrimaryKeys.Count);

            foreach (PropertyDescriptor keyPropertyDescriptor in typeDescriptor.PrimaryKeys)
            {
                object keyVal = keyPropertyDescriptor.GetValue(entity);
                keyValueMap.Add(keyPropertyDescriptor, keyVal);
            }

            DbTable dbTable = table == null ? typeDescriptor.Table : new DbTable(table, typeDescriptor.Table.Schema);

            PropertyDescriptor timestampProperty = typeDescriptor.PropertyDescriptors.Where(a => a.IsTimestamp()).FirstOrDefault();

            if (timestampProperty != null)
            {
                object timestampValue = timestampProperty.GetValue(entity);
                if (timestampValue != null)
                {
                    keyValueMap[timestampProperty] = timestampValue;
                }
            }

            DbExpression       conditionExp = PrimaryKeyHelper.MakeCondition(keyValueMap, dbTable);
            DbDeleteExpression e            = new DbDeleteExpression(dbTable, conditionExp);

            return(this.ExecuteNonQuery(e));
        }
示例#10
0
        /// <summary>
        /// dbContext.Update&lt;User&gt;(user, a =&gt; a.Id == 1)
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="dbContext"></param>
        /// <param name="entity"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public static int Update <TEntity>(this IDbContext dbContext, TEntity entity, Expression <Func <TEntity, bool> > condition)
        {
            PublicHelper.CheckNull(dbContext);
            PublicHelper.CheckNull(entity);
            PublicHelper.CheckNull(condition);

            Type           entityType     = typeof(TEntity);
            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entityType);

            List <MemberBinding> bindings = new List <MemberBinding>();

            ConstantExpression entityConstantExp = Expression.Constant(entity);

            foreach (PrimitivePropertyDescriptor propertyDescriptor in typeDescriptor.PrimitivePropertyDescriptors)
            {
                if (propertyDescriptor.IsPrimaryKey || propertyDescriptor.IsAutoIncrement)
                {
                    continue;
                }

                Expression       entityMemberAccess = Expression.MakeMemberAccess(entityConstantExp, propertyDescriptor.Property);
                MemberAssignment bind = Expression.Bind(propertyDescriptor.Property, entityMemberAccess);

                bindings.Add(bind);
            }

            return(UpdateOnly(dbContext, condition, bindings));
        }
示例#11
0
        string CreateTableScript(Type entityType)
        {
            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entityType);
            string         tableName      = typeDescriptor.Table.Name;

            StringBuilder sb = new StringBuilder();

            sb.Append($"CREATE TABLE IF NOT EXISTS {this.QuoteName(tableName)}(");

            string c = "";

            foreach (var propertyDescriptor in typeDescriptor.PrimitivePropertyDescriptors)
            {
                sb.AppendLine(c);
                sb.Append($"  {this.BuildColumnPart(propertyDescriptor)}");
                c = ",";
            }

            if (typeDescriptor.PrimaryKeys.Count > 0)
            {
                string key = typeDescriptor.PrimaryKeys.First().Column.Name;
                sb.AppendLine(c);
                sb.Append($"  PRIMARY KEY ({this.QuoteName(key)}) USING BTREE");
            }

            sb.AppendLine();
            sb.Append(");");

            return(sb.ToString());
        }
示例#12
0
        public override TEntity Insert <TEntity>(TEntity entity, string table)
        {
            PublicHelper.CheckNull(entity);

            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity));

            List <PropertyDescriptor> outputColumns = new List <PropertyDescriptor>();
            Dictionary <PropertyDescriptor, DbExpression> insertColumns = new Dictionary <PropertyDescriptor, DbExpression>();

            foreach (PropertyDescriptor propertyDescriptor in typeDescriptor.PropertyDescriptors)
            {
                if (propertyDescriptor.IsAutoIncrement)
                {
                    outputColumns.Add(propertyDescriptor);
                    continue;
                }

                if (propertyDescriptor.HasSequence())
                {
                    DbMethodCallExpression getNextValueForSequenceExp = PublicHelper.MakeNextValueForSequenceDbExpression(propertyDescriptor);
                    insertColumns.Add(propertyDescriptor, getNextValueForSequenceExp);
                    outputColumns.Add(propertyDescriptor);
                    continue;
                }

                object val = propertyDescriptor.GetValue(entity);

                DbExpression valExp = DbExpression.Parameter(val, propertyDescriptor.PropertyType, propertyDescriptor.Column.DbType);
                insertColumns.Add(propertyDescriptor, valExp);
            }

            DbTable            dbTable = table == null ? typeDescriptor.Table : new DbTable(table, typeDescriptor.Table.Schema);
            DbInsertExpression e       = new DbInsertExpression(dbTable);

            foreach (var kv in insertColumns)
            {
                e.InsertColumns.Add(kv.Key.Column, kv.Value);
            }

            e.Returns.AddRange(outputColumns.Select(a => a.Column));

            List <DbParam> parameters;

            this.ExecuteNonQuery(e, out parameters);

            List <DbParam> outputParams = parameters.Where(a => a.Direction == ParamDirection.Output).ToList();

            for (int i = 0; i < outputColumns.Count; i++)
            {
                PropertyDescriptor propertyDescriptor = outputColumns[i];
                string             putputColumnName   = Utils.GenOutputColumnParameterName(propertyDescriptor.Column.Name);
                DbParam            outputParam        = outputParams.Where(a => a.Name == putputColumnName).First();
                var outputValue = PublicHelper.ConvertObjType(outputParam.Value, propertyDescriptor.PropertyType);
                outputColumns[i].SetValue(entity, outputValue);
            }

            return(entity);
        }
示例#13
0
        public override TEntity Insert <TEntity>(TEntity entity, string table)
        {
            PublicHelper.CheckNull(entity);

            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entity.GetType());

            Dictionary <PropertyDescriptor, object> keyValueMap = CreateKeyValueMap(typeDescriptor);

            Dictionary <PropertyDescriptor, object> sequenceValues = this.GetSequenceValues(typeDescriptor.PropertyDescriptors.Where(a => a.HasSequence()).ToList());

            Dictionary <PropertyDescriptor, DbExpression> insertColumns = new Dictionary <PropertyDescriptor, DbExpression>();

            foreach (PropertyDescriptor propertyDescriptor in typeDescriptor.PropertyDescriptors)
            {
                object val = null;
                if (propertyDescriptor.HasSequence())
                {
                    val = sequenceValues[propertyDescriptor];
                }
                else
                {
                    val = propertyDescriptor.GetValue(entity);
                }

                if (propertyDescriptor.IsPrimaryKey)
                {
                    keyValueMap[propertyDescriptor] = val;
                }

                DbExpression valExp = DbExpression.Parameter(val, propertyDescriptor.PropertyType, propertyDescriptor.Column.DbType);
                insertColumns.Add(propertyDescriptor, valExp);
            }

            PropertyDescriptor nullValueKey = keyValueMap.Where(a => a.Value == null).Select(a => a.Key).FirstOrDefault();

            if (nullValueKey != null)
            {
                throw new ChloeException(string.Format("The primary key '{0}' could not be null.", nullValueKey.Property.Name));
            }

            DbTable            dbTable = table == null ? typeDescriptor.Table : new DbTable(table, typeDescriptor.Table.Schema);
            DbInsertExpression e       = new DbInsertExpression(dbTable);

            foreach (var kv in insertColumns)
            {
                e.InsertColumns.Add(kv.Key.Column, kv.Value);
            }

            this.ExecuteSqlCommand(e);

            foreach (var kv in sequenceValues)
            {
                kv.Key.SetValue(entity, kv.Value);
            }

            return(entity);
        }
示例#14
0
        /// <summary>
        /// dbContext.Query&lt;User&gt;().MapTo&lt;UserModel&gt;()
        /// <para>该方法调用者的 IQuery.ElementType 必须是实体类型</para>
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static IQuery <TModel> MapTo <TModel>(this IQuery source)
        {
            /*
             * 根据 TEntity 与 TModel 属性对应关系构建 selector 表达式树,最后调用 Select() 方法
             * dbContext.Query<User>().Select(a => new UserModel() { Id = a.Id, Name = a.Name });
             * ps: 只支持简单的映射,不支持复杂的对应关系
             */

            PublicHelper.CheckNull(source);

            List <MemberBinding> bindings = new List <MemberBinding>();

            Type entityType = source.ElementType;
            Type modelType  = typeof(TModel);

            TypeDescriptor typeDescriptor             = EntityTypeContainer.GetDescriptor(entityType);
            var            mappingPropertyDescriptors = typeDescriptor.PrimitivePropertyDescriptors.ToDictionary(a => a.Property.Name, a => a);

            var props = modelType.GetProperties();
            ParameterExpression parameter = Expression.Parameter(typeDescriptor.Definition.Type, "a");

            foreach (var prop in props)
            {
                if (prop.GetSetMethod() == null)
                {
                    continue;
                }

                PrimitivePropertyDescriptor mapPropertyDescriptor;
                if (mappingPropertyDescriptors.TryGetValue(prop.Name, out mapPropertyDescriptor) == false)
                {
                    continue;
                }

                Expression sourceMemberAccess = Expression.MakeMemberAccess(parameter, mapPropertyDescriptor.Property);
                if (prop.PropertyType != mapPropertyDescriptor.PropertyType)
                {
                    sourceMemberAccess = Expression.Convert(sourceMemberAccess, prop.PropertyType);
                }

                MemberAssignment bind = Expression.Bind(prop, sourceMemberAccess);
                bindings.Add(bind);
            }

            NewExpression newExp       = Expression.New(modelType);
            Expression    selectorBody = Expression.MemberInit(newExp, bindings);

            Type             funcType = typeof(Func <,>).MakeGenericType(entityType, modelType);
            LambdaExpression selector = Expression.Lambda(funcType, selectorBody, parameter);

            MethodInfo methodInfo_Select = source.GetType().GetMethod("Select").MakeGenericMethod(modelType);
            var        obj = methodInfo_Select.Invoke(source, new object[] { selector });

            return((IQuery <TModel>)obj);
        }
示例#15
0
        public virtual int Update <TEntity>(Expression <Func <TEntity, bool> > condition, Expression <Func <TEntity, TEntity> > content, string table, int limits)
        {
            Utils.CheckNull(condition);
            Utils.CheckNull(content);

            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity));

            Dictionary <MemberInfo, Expression> updateColumns = InitMemberExtractor.Extract(content);

            DbTable explicitDbTable = null;

            if (table != null)
            {
                explicitDbTable = new DbTable(table, typeDescriptor.Table.Schema);
            }
            DefaultExpressionParser expressionParser = typeDescriptor.GetExpressionParser(explicitDbTable);

            DbExpression conditionExp = expressionParser.ParseFilterPredicate(condition);

            MySqlDbUpdateExpression e = new MySqlDbUpdateExpression(explicitDbTable ?? typeDescriptor.Table, conditionExp);

            foreach (var kv in updateColumns)
            {
                MemberInfo         key = kv.Key;
                PropertyDescriptor propertyDescriptor = typeDescriptor.TryGetPropertyDescriptor(key);

                if (propertyDescriptor == null)
                {
                    throw new ChloeException(string.Format("The member '{0}' does not map any column.", key.Name));
                }

                if (propertyDescriptor.IsPrimaryKey)
                {
                    throw new ChloeException(string.Format("Could not update the primary key '{0}'.", propertyDescriptor.Column.Name));
                }

                if (propertyDescriptor.IsAutoIncrement)
                {
                    throw new ChloeException(string.Format("Could not update the identity column '{0}'.", propertyDescriptor.Column.Name));
                }

                e.UpdateColumns.Add(propertyDescriptor.Column, expressionParser.Parse(kv.Value));
            }

            e.Limits = limits;

            if (e.UpdateColumns.Count == 0)
            {
                return(0);
            }

            return(this.ExecuteSqlCommand(e));
        }
示例#16
0
        static async Task <int> UpdateOnly <TEntity>(IDbContext dbContext, TEntity entity, string[] fields, bool @async)
        {
            PublicHelper.CheckNull(dbContext);
            PublicHelper.CheckNull(entity);
            PublicHelper.CheckNull(fields);

            /* 支持 context.UpdateOnly<User>(user, "Name,Age", "NickName"); */
            fields = fields.SelectMany(a => a.Split(',')).Select(a => a.Trim()).ToArray();

            if (fields.Length == 0)
            {
                throw new ArgumentException("fields");
            }

            Type           entityType     = typeof(TEntity);
            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entityType);

            List <MemberBinding> bindings = new List <MemberBinding>();

            ConstantExpression entityConstantExp = Expression.Constant(entity);

            foreach (string field in fields)
            {
                MemberInfo memberInfo         = entityType.GetMember(field)[0];
                var        propertyDescriptor = typeDescriptor.FindPrimitivePropertyDescriptor(memberInfo);

                if (propertyDescriptor == null)
                {
                    throw new ArgumentException(string.Format("Could not find the member '{0}' from entity.", propertyDescriptor.Column.Name));
                }

                Expression       entityMemberAccess = Expression.MakeMemberAccess(entityConstantExp, memberInfo);
                MemberAssignment bind = Expression.Bind(memberInfo, entityMemberAccess);

                bindings.Add(bind);
            }

            ParameterExpression parameter     = Expression.Parameter(entityType, "a");
            Expression          conditionBody = null;

            foreach (PrimitivePropertyDescriptor primaryKey in typeDescriptor.PrimaryKeys)
            {
                Expression propOrField = Expression.PropertyOrField(parameter, primaryKey.Property.Name);
                Expression keyValue    = Expression.MakeMemberAccess(entityConstantExp, primaryKey.Property);
                Expression e           = Expression.Equal(propOrField, keyValue);
                conditionBody = conditionBody == null ? e : Expression.AndAlso(conditionBody, e);
            }

            Expression <Func <TEntity, bool> > condition = Expression.Lambda <Func <TEntity, bool> >(conditionBody, parameter);

            return(await UpdateOnly(dbContext, condition, bindings, @async));
        }
示例#17
0
        public override int Update <TEntity>(Expression <Func <TEntity, bool> > condition, Expression <Func <TEntity, TEntity> > content, string table)
        {
            PublicHelper.CheckNull(condition);
            PublicHelper.CheckNull(content);

            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity));

            Dictionary <MemberInfo, Expression> updateColumns = InitMemberExtractor.Extract(content);

            DbTable explicitDbTable = null;

            if (table != null)
            {
                explicitDbTable = new DbTable(table, typeDescriptor.Table.Schema);
            }
            DefaultExpressionParser expressionParser = typeDescriptor.GetExpressionParser(explicitDbTable);

            DbExpression conditionExp = expressionParser.ParseFilterPredicate(condition);

            DbUpdateExpression e = new DbUpdateExpression(explicitDbTable ?? typeDescriptor.Table, conditionExp);

            foreach (var kv in updateColumns)
            {
                MemberInfo         key = kv.Key;
                PropertyDescriptor propertyDescriptor = typeDescriptor.TryGetPropertyDescriptor(key);

                if (propertyDescriptor == null)
                {
                    throw new ChloeException(string.Format("The member '{0}' does not map any column.", key.Name));
                }

                if (propertyDescriptor.IsPrimaryKey)
                {
                    throw new ChloeException(string.Format("Could not update the primary key '{0}'.", propertyDescriptor.Column.Name));
                }

                bool hasSequence = propertyDescriptor.HasSequence();
                if (hasSequence)
                {
                    throw new ChloeException(string.Format("Could not update the column '{0}', because it's mapping member has define a sequence.", propertyDescriptor.Column.Name));
                }

                e.UpdateColumns.Add(propertyDescriptor.Column, expressionParser.Parse(kv.Value));
            }

            if (e.UpdateColumns.Count == 0)
            {
                return(0);
            }

            return(this.ExecuteNonQuery(e));
        }
示例#18
0
        public IQuery <T> IncludeAll()
        {
            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(T));

            object lastQuery = this;

            for (int i = 0; i < typeDescriptor.NavigationPropertyDescriptors.Count; i++)
            {
                PropertyDescriptor propertyDescriptor = typeDescriptor.NavigationPropertyDescriptors[i];
                lastQuery = this.Include(typeDescriptor, lastQuery, propertyDescriptor);
            }

            return((IQuery <T>)lastQuery);
        }
示例#19
0
        protected virtual async Task <int> Delete <TEntity>(Expression <Func <TEntity, bool> > condition, string table, bool @async)
        {
            PublicHelper.CheckNull(condition);

            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity));

            DbTable dbTable = typeDescriptor.GenDbTable(table);
            DefaultExpressionParser expressionParser = typeDescriptor.GetExpressionParser(dbTable);
            DbExpression            conditionExp     = expressionParser.ParseFilterPredicate(condition);

            DbDeleteExpression e = new DbDeleteExpression(dbTable, conditionExp);

            return(await this.ExecuteNonQuery(e, @async));
        }
示例#20
0
        /// <summary>
        /// dbContext.Query&lt;User&gt;().Ignore&lt;User&gt;("Name,Age", "NickName")
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="source"></param>
        /// <param name="fields"></param>
        /// <returns></returns>
        public static IQuery <TEntity> Ignore <TEntity>(this IQuery <TEntity> source, params string[] fields)
        {
            PublicHelper.CheckNull(source);

            if (fields == null)
            {
                return(source);
            }

            /* 支持 source.Ignore<User>("Name,Age", "NickName"); */
            fields = fields.SelectMany(a => a.Split(',')).Select(a => a.Trim()).ToArray();

            if (fields.Length == 0)
            {
                return(source);
            }

            List <MemberBinding> bindings = new List <MemberBinding>();

            Type entityType = source.ElementType;

            TypeDescriptor typeDescriptor             = EntityTypeContainer.GetDescriptor(entityType);
            var            mappingPropertyDescriptors = typeDescriptor.PrimitivePropertyDescriptors.ToList();

            ParameterExpression parameter = Expression.Parameter(entityType, "a");

            foreach (var mappingPropertyDescriptor in mappingPropertyDescriptors)
            {
                if (fields.Any(a => a == mappingPropertyDescriptor.Property.Name))
                {
                    continue;
                }

                Expression       sourceMemberAccess = Expression.MakeMemberAccess(parameter, mappingPropertyDescriptor.Property);
                MemberAssignment bind = Expression.Bind(mappingPropertyDescriptor.Property, sourceMemberAccess);
                bindings.Add(bind);
            }

            if (bindings.Count == 0)
            {
                throw new Exception("There are no fields to map after ignore.");
            }

            NewExpression newExp       = Expression.New(entityType);
            Expression    selectorBody = Expression.MemberInit(newExp, bindings);

            Expression <Func <TEntity, TEntity> > selector = Expression.Lambda <Func <TEntity, TEntity> >(selectorBody, parameter);

            return(source.Select(selector));
        }
示例#21
0
        static ResultElement CreateResultElement(Type type, string explicitTableName, LockType lockType, ScopeParameterDictionary scopeParameters, KeyDictionary <string> scopeTables)
        {
            if (type.IsAbstract || type.IsInterface)
            {
                throw new ArgumentException("The type of input can not be abstract class or interface.");
            }

            //TODO init _resultElement
            ResultElement resultElement = new ResultElement(scopeParameters, scopeTables);

            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(type);

            DbTable dbTable = typeDescriptor.Table;

            if (explicitTableName != null)
            {
                dbTable = new DbTable(explicitTableName, dbTable.Schema);
            }
            string alias = resultElement.GenerateUniqueTableAlias(dbTable.Name);

            resultElement.FromTable = CreateRootTable(dbTable, alias, lockType);

            ConstructorInfo constructor = typeDescriptor.Definition.Type.GetConstructor(Type.EmptyTypes);

            if (constructor == null)
            {
                throw new ArgumentException(string.Format("The type of '{0}' does't define a none parameter constructor.", type.FullName));
            }

            MappingObjectExpression moe = new MappingObjectExpression(constructor);

            DbTableSegment tableExp = resultElement.FromTable.Table;
            DbTable        table    = new DbTable(alias);

            foreach (PropertyDescriptor item in typeDescriptor.PropertyDescriptors)
            {
                DbColumnAccessExpression columnAccessExpression = new DbColumnAccessExpression(table, item.Column);

                moe.AddMappingMemberExpression(item.Property, columnAccessExpression);
                if (item.IsPrimaryKey)
                {
                    moe.PrimaryKey = columnAccessExpression;
                }
            }

            resultElement.MappingObjectExpression = moe;

            return(resultElement);
        }
示例#22
0
        /// <summary>
        ///     Gets the name of the data table used by this type.
        /// </summary>
        /// <param name="typeId">The id.</param>
        /// <returns>
        ///     The name of the data table used by this entity type.
        /// </returns>
        public static string GetDataTableName(long typeId)
        {
            EntityTypeContainer container;

            /////
            // Hit the cache.
            /////
            Instance.TryGetValue(typeId, out container);

            if (container == null || (container.DataTableNameMember == null && !container.DataTableNameResolvedMember))
            {
                /////
                // Initialize the dataTable to be a relationship.
                /////
                string dataTableName  = "Relationship";
                long   dbFieldTableId = WellKnownAliases.CurrentTenant.DbFieldTable;

                using (DatabaseContext ctx = DatabaseContext.GetContext())
                {
                    using (IDbCommand command = ctx.CreateCommand())
                    {
                        command.CommandText = "dbo.spData_NVarCharRead";
                        command.CommandType = CommandType.StoredProcedure;

                        ctx.AddParameter(command, "@entityId", DbType.Int64, typeId);
                        ctx.AddParameter(command, "@tenantId", DbType.Int64, RequestContext.TenantId);
                        ctx.AddParameter(command, "@fieldId", DbType.Int64, dbFieldTableId);

                        using (IDataReader reader = command.ExecuteReader())
                        {
                            if (reader.Read() && !reader.IsDBNull(3))
                            {
                                dataTableName = reader.GetString(3);
                            }
                        }
                    }
                }

                if (container == null)
                {
                    container        = new EntityTypeContainer(typeId);
                    Instance[typeId] = container;
                }

                container.DataTableName = dataTableName;
            }

            return(container.DataTableName);
        }
示例#23
0
        public IFitter CreateFitter(IDbContext dbContext)
        {
            List <Tuple <PropertyDescriptor, IFitter> > includings = new List <Tuple <PropertyDescriptor, IFitter> >();
            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(this.ConstructorDescriptor.ConstructorInfo.DeclaringType);

            foreach (var item in this.ComplexMembers.Concat(this.CollectionMembers))
            {
                IFitter propFitter = item.Value.CreateFitter(dbContext);
                includings.Add(new Tuple <PropertyDescriptor, IFitter>(typeDescriptor.GetPropertyDescriptor(item.Key), propFitter));
            }

            ComplexObjectFitter fitter = new ComplexObjectFitter(includings);

            return(fitter);
        }
示例#24
0
        async Task SaveOneToOne(ComplexPropertyDescriptor navPropertyDescriptor, object owner, TypeDescriptor ownerTypeDescriptor, bool @async)
        {
            /*
             * 1:1
             * T    <1:1>    TOther
             * T.TOther <--> TOther.T
             * T.Id <--> TOther.Id
             */

            //owner is T
            //navPropertyDescriptor is T.TOther
            //TypeDescriptor of T.TOther
            TypeDescriptor navTypeDescriptor = EntityTypeContainer.GetDescriptor(navPropertyDescriptor.PropertyType);
            //TOther.T
            ComplexPropertyDescriptor TOtherDotT = navTypeDescriptor.ComplexPropertyDescriptors.Where(a => a.PropertyType == ownerTypeDescriptor.Definition.Type).FirstOrDefault();

            bool isOneToOne = TOtherDotT != null;

            if (!isOneToOne)
            {
                return;
            }

            //instance of T.TOther
            object navValue = navPropertyDescriptor.GetValue(owner);

            if (navValue == null)
            {
                return;
            }

            //T.Id
            PrimitivePropertyDescriptor foreignKeyProperty = navPropertyDescriptor.ForeignKeyProperty;

            if (foreignKeyProperty.IsAutoIncrement || foreignKeyProperty.HasSequence())
            {
                //value of T.Id
                object foreignKeyValue = foreignKeyProperty.GetValue(owner);

                //T.TOther.Id = T.Id
                TOtherDotT.ForeignKeyProperty.SetValue(navValue, foreignKeyValue);
            }

            MethodInfo saveMethod = GetSaveMethod(navPropertyDescriptor.PropertyType);
            //DbContext.Save(navValue, ownerTypeDescriptor, @async);
            Task  task = (Task)saveMethod.Invoke(this, navValue, ownerTypeDescriptor, @async);
            await task;
        }
示例#25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="fieldsLambdaExpression">a => new { a.Name, a.Age } or a => new object[] { a.Name, a.Age }</param>
        /// <returns></returns>
        public static List <string> Resolve(LambdaExpression fieldsLambdaExpression)
        {
            ParameterExpression parameterExpression = fieldsLambdaExpression.Parameters[0];

            var body = ExpressionExtension.StripConvert(fieldsLambdaExpression.Body);

            ReadOnlyCollection <Expression> fieldExps = null;

            NewExpression newExpression = body as NewExpression;

            if (newExpression != null && newExpression.Type.IsAnonymousType())
            {
                fieldExps = newExpression.Arguments;
            }
            else
            {
                NewArrayExpression newArrayExpression = body as NewArrayExpression;
                if (newArrayExpression == null)
                {
                    throw new NotSupportedException(fieldsLambdaExpression.ToString());
                }

                fieldExps = newArrayExpression.Expressions;
            }

            Type           entityType     = parameterExpression.Type;
            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entityType);

            List <string> fields = new List <string>(fieldExps.Count);

            foreach (var item in fieldExps)
            {
                MemberExpression memberExp = ExpressionExtension.StripConvert(item) as MemberExpression;
                if (memberExp == null)
                {
                    throw new NotSupportedException(item.ToString());
                }

                if (memberExp.Expression != parameterExpression)
                {
                    throw new NotSupportedException(item.ToString());
                }

                fields.Add(memberExp.Member.Name);
            }

            return(fields);
        }
示例#26
0
        public virtual int Delete <TEntity>(Expression <Func <TEntity, bool> > condition, string table, int limits)
        {
            PublicHelper.CheckNull(condition);

            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity));

            DbTable dbTable = PublicHelper.CreateDbTable(typeDescriptor, table);
            DefaultExpressionParser expressionParser = typeDescriptor.GetExpressionParser(dbTable);
            DbExpression            conditionExp     = expressionParser.ParseFilterPredicate(condition);

            MySqlDbDeleteExpression e = new MySqlDbDeleteExpression(dbTable, conditionExp);

            e.Limits = limits;

            return(this.ExecuteNonQuery(e));
        }
示例#27
0
        /// <summary>
        ///     Determines whether the specified type id is literal.
        /// </summary>
        /// <param name="typeId">The type id.</param>
        /// <returns>
        ///     <c>true</c> if the specified type id is literal; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsLiteral(long typeId)
        {
            EntityTypeContainer container;

            /////
            // Hit the cache.
            /////
            Instance.TryGetValue(typeId, out container);

            if (container == null)
            {
                container        = new EntityTypeContainer(typeId);
                Instance[typeId] = container;
            }

            return(container.IsLiteralInner);
        }
示例#28
0
        /// <summary>
        /// 传入一个 dto 对象插入数据。dto 需要与实体建立映射关系,否则会报错
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <typeparam name="TDto"></typeparam>
        /// <param name="dbContext"></param>
        /// <param name="dto"></param>
        /// <returns></returns>
        public static TEntity InsertFromDto <TEntity, TDto>(this IDbContext dbContext, TDto dto)
        {
            /*
             * 支持自动设置 主键=guid
             * 支持自动设置 CreationTime=DateTime.Now
             * 支持自动设置 IsDeleted=false
             */

            Utils.CheckNull(dto);

            TEntity entity = AceMapper.Map <TEntity>(dto);

            Type           entityType     = typeof(TEntity);
            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entityType);

            /* 设置 主键=guid */
            if (typeDescriptor.PrimaryKeys.Count < 2) /* 只有无主键或单一主键的时候 */
            {
                var primaryKeyDescriptor = typeDescriptor.PrimaryKeys.FirstOrDefault();
                if (primaryKeyDescriptor != null && primaryKeyDescriptor.IsAutoIncrement == false)
                {
                    var keyValue = primaryKeyDescriptor.GetValue(entity);
                    if (keyValue.IsDefaultValueOfType(primaryKeyDescriptor.PropertyType) || string.Empty.Equals(keyValue))
                    {
                        /* 如果未设置主键值,则自动设置为 guid */
                        if (primaryKeyDescriptor.PropertyType == typeof(string))
                        {
                            primaryKeyDescriptor.SetValue(entity, IdHelper.CreateSnowflakeId().ToString());
                        }
                        else if (primaryKeyDescriptor.PropertyType.GetUnderlyingType() == typeof(Guid))
                        {
                            primaryKeyDescriptor.SetValue(entity, Guid.NewGuid());
                        }
                    }
                }
            }


            /* 设置 CreationTime=DateTime.Now */
            SetValueIfNeeded(entity, typeDescriptor, "CreationTime", DateTime.Now);

            /* 设置 IsDeleted=false */
            SetValueIfNeeded(entity, typeDescriptor, "IsDeleted", false);

            return(dbContext.Insert(entity));
        }
示例#29
0
        public static TypeDescriptor GetPropertyTypeDescriptor(this PropertyDescriptor propertyDescriptor)
        {
            ComplexPropertyDescriptor complexPropertyDescriptor = propertyDescriptor as ComplexPropertyDescriptor;

            Type type;

            if (complexPropertyDescriptor != null)
            {
                type = propertyDescriptor.PropertyType;
            }
            else
            {
                type = (propertyDescriptor as CollectionPropertyDescriptor).ElementType;
            }

            return(EntityTypeContainer.GetDescriptor(type));
        }
示例#30
0
        /// <summary>
        ///     Gets the assignable types for the specified type name.
        /// </summary>
        /// <param name="typeId">The type id.</param>
        /// <returns>
        ///     A set of type identifiers that represent the assignable types for the specified type.
        /// </returns>
        public static HashSet <long> GetAssignableTypes(long typeId)
        {
            EntityTypeContainer container;

            /////
            // Hit the cache.
            /////
            Instance.TryGetValue(typeId, out container);

            if (container == null || container.AssignableTypesMember == null)
            {
                var assignableTypes = new HashSet <long>
                {
                    typeId
                };

                /////
                // Add the current type.
                /////

                IEntity entityType = Entity.Get(new EntityRef(typeId));

                if (entityType != null)
                {
                    long inheritsId = WellKnownAliases.CurrentTenant.Inherits;

                    var inheritsEntityRef = new EntityRef(inheritsId);

                    /////
                    // Add the 'inherits' types (base types).
                    /////
                    AggregateTypes(entityType, inheritsEntityRef, Direction.Forward, assignableTypes);
                }

                if (container == null)
                {
                    container        = new EntityTypeContainer(typeId);
                    Instance[typeId] = container;
                }

                container.AssignableTypes = assignableTypes;
            }

            return(container.AssignableTypes);
        }