Example #1
0
        public virtual int Delete <TEntity>(TEntity entity)
        {
            Utils.CheckNull(entity);

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

            EnsureEntityHasPrimaryKey(typeDescriptor);

            MappingMemberDescriptor keyMemberDescriptor = typeDescriptor.PrimaryKey;
            MemberInfo keyMember = typeDescriptor.PrimaryKey.MemberInfo;

            var keyVal = keyMemberDescriptor.GetValue(entity);

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

            DbExpression left         = new DbColumnAccessExpression(typeDescriptor.Table, keyMemberDescriptor.Column);
            DbExpression right        = new DbParameterExpression(keyVal);
            DbExpression conditionExp = new DbEqualExpression(left, right);

            DbDeleteExpression e = new DbDeleteExpression(typeDescriptor.Table, conditionExp);

            return(this.ExecuteSqlCommand(e));
        }
Example #2
0
        public virtual void TrackEntity(object entity)
        {
            Utils.CheckNull(entity);
            Type entityType = entity.GetType();

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

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

            TrackEntityCollection collection;

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

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

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

            collection.TryAddEntity(entity);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="fieldsLambdaExpression">a => new object[] { a.Name, a.Age }</param>
        /// <returns></returns>
        public static List <string> Pick(LambdaExpression fieldsLambdaExpression)
        {
            ParameterExpression parameterExpression = fieldsLambdaExpression.Parameters[0];

            NewArrayExpression newArrayExpression = fieldsLambdaExpression.Body as NewArrayExpression;

            if (newArrayExpression == null)
            {
                throw new NotSupportedException(fieldsLambdaExpression.ToString());
            }

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

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

            foreach (var item in newArrayExpression.Expressions)
            {
                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);
        }
Example #4
0
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public TEntity Edit(TEntity entity)
        {
            Checks.NotNull(entity, "entity");

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

            object keyVal = null;
            MappingMemberDescriptor keyMemberDescriptor = null;

            Dictionary <MappingMemberDescriptor, DbExpression> updateColumns = new Dictionary <MappingMemberDescriptor, DbExpression>();

            foreach (var kv in typeDescriptor.MappingMemberDescriptors)
            {
                MemberInfo member = kv.Key;
                MappingMemberDescriptor memberDescriptor = kv.Value;

                object val = memberDescriptor.GetValue(entity);
                if (memberDescriptor.SZColumnAttribute.IsKey)
                {
                    if (val == null)
                    {
                        throw new SZORMException("主键值不允许为空.");
                    }
                    keyVal = val;
                    keyMemberDescriptor = memberDescriptor;
                    continue;
                }

                if (memberDescriptor.SZColumnAttribute.IsEditTime)
                {
                    val = DateTime.Now;
                    memberDescriptor.SetValue(entity, val);
                }


                DbExpression valExp = DbExpression.Parameter(val, memberDescriptor.MemberInfoType);
                updateColumns.Add(memberDescriptor, valExp);
            }

            DbExpression left         = new DbColumnAccessExpression(typeDescriptor.Table, keyMemberDescriptor.Column);
            DbExpression right        = DbExpression.Parameter(keyVal, keyMemberDescriptor.MemberInfoType);
            DbExpression conditionExp = new DbEqualExpression(left, right);

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

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

            IDbExpressionTranslator translator = this.DbContext.DatabaseProvider.CreateDbExpressionTranslator();
            List <DbParam>          parameters;
            string sql = translator.Translate(e, out parameters);

            this.DbContext.ExecuteNoQuery(sql, parameters.ToArray());

            return(entity);
        }
Example #5
0
        /// <summary>
        /// 利用 SqlBulkCopy 批量插入数据。
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entities"></param>
        /// <param name="batchSize">设置 SqlBulkCopy.BatchSize 的值</param>
        /// <param name="bulkCopyTimeout">设置 SqlBulkCopy.BulkCopyTimeout 的值</param>
        /// <param name="keepIdentity">是否保留源标识值。false 由数据库分配标识值。</param>
        public virtual void BulkInsert <TEntity>(List <TEntity> entities, int?batchSize = null, int?bulkCopyTimeout = null, bool keepIdentity = false)
        {
            Utils.CheckNull(entities);

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

            DataTable dtToWrite = ToSqlBulkCopyDataTable(entities, typeDescriptor);

            SqlBulkCopy sbc = null;

            bool          shouldCloseConnection = false;
            SqlConnection conn = this.Session.CurrentConnection as SqlConnection;

            try
            {
                SqlTransaction externalTransaction = null;
                if (this.Session.IsInTransaction)
                {
                    externalTransaction = this.Session.CurrentTransaction as SqlTransaction;
                }

                SqlBulkCopyOptions sqlBulkCopyOptions = keepIdentity ? (SqlBulkCopyOptions.KeepNulls | SqlBulkCopyOptions.KeepIdentity) : SqlBulkCopyOptions.KeepNulls;
                sbc = new SqlBulkCopy(conn, sqlBulkCopyOptions, externalTransaction);

                using (sbc)
                {
                    if (batchSize != null)
                    {
                        sbc.BatchSize = batchSize.Value;
                    }

                    sbc.DestinationTableName = AppendTableName(typeDescriptor.Table);

                    if (bulkCopyTimeout != null)
                    {
                        sbc.BulkCopyTimeout = bulkCopyTimeout.Value;
                    }

                    if (conn.State != ConnectionState.Open)
                    {
                        conn.Open();
                        shouldCloseConnection = true;
                    }

                    sbc.WriteToServer(dtToWrite);
                }
            }
            finally
            {
                if (conn != null)
                {
                    if (shouldCloseConnection && conn.State == ConnectionState.Open)
                    {
                        conn.Close();
                    }
                }
            }
        }
Example #6
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: 只支持简单的映射,不支持复杂的对应关系
             */

            Utils.CheckNull(source);

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

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

            TypeDescriptor typeDescriptor           = TypeDescriptor.GetDescriptor(entityType);
            var            mappingMemberDescriptors = typeDescriptor.MappingMemberDescriptors.Select(a => a.Value).ToDictionary(a => a.MemberInfo.Name, a => a);

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

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

                MappingMemberDescriptor mapMemberDescriptor;
                if (mappingMemberDescriptors.TryGetValue(prop.Name, out mapMemberDescriptor) == false)
                {
                    continue;
                }

                Expression sourceMemberAccess = Expression.MakeMemberAccess(parameter, mapMemberDescriptor.MemberInfo);
                if (prop.PropertyType != mapMemberDescriptor.MemberInfoType)
                {
                    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);
        }
Example #7
0
        public virtual int Delete <TEntity>(Expression <Func <TEntity, bool> > condition)
        {
            Utils.CheckNull(condition);

            TypeDescriptor typeDescriptor = TypeDescriptor.GetDescriptor(typeof(TEntity));
            DbExpression   conditionExp   = typeDescriptor.Visitor.VisitFilterPredicate(condition);

            DbDeleteExpression e = new DbDeleteExpression(typeDescriptor.Table, conditionExp);

            return(this.ExecuteSqlCommand(e));
        }
Example #8
0
        public virtual object Insert <T>(Expression <Func <T> > body)
        {
            Utils.CheckNull(body);

            TypeDescriptor typeDescriptor = TypeDescriptor.GetDescriptor(typeof(T));

            EnsureMappingTypeHasPrimaryKey(typeDescriptor);

            MappingMemberDescriptor keyMemberDescriptor = typeDescriptor.PrimaryKey;

            Dictionary <MemberInfo, Expression> insertColumns = InitMemberExtractor.Extract(body);

            DbInsertExpression e = new DbInsertExpression(typeDescriptor.Table);

            object keyVal = null;

            foreach (var kv in insertColumns)
            {
                MemberInfo key = kv.Key;
                MappingMemberDescriptor memberDescriptor = typeDescriptor.TryGetMappingMemberDescriptor(key);

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

                if (memberDescriptor.IsPrimaryKey)
                {
                    object val = ExpressionEvaluator.Evaluate(kv.Value);
                    if (val == null)
                    {
                        throw new ChloeException(string.Format("The primary key '{0}' could not be null.", memberDescriptor.MemberInfo.Name));
                    }
                    else
                    {
                        keyVal = val;
                        e.InsertColumns.Add(memberDescriptor.Column, DbExpression.Parameter(keyVal));
                        continue;
                    }
                }

                e.InsertColumns.Add(memberDescriptor.Column, typeDescriptor.Visitor.Visit(kv.Value));
            }

            //主键为空
            if (keyVal == null)
            {
                throw new ChloeException(string.Format("The primary key '{0}' could not be null.", keyMemberDescriptor.MemberInfo.Name));
            }

            this.ExecuteSqlCommand(e);
            return(keyVal);
        }
Example #9
0
        /// <summary>
        /// dbContext.UpdateOnly&lt;User&gt;(user, "Name,Age", "NickName")
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="dbContext"></param>
        /// <param name="entity"></param>
        /// <param name="fields"></param>
        /// <returns></returns>
        public static int UpdateOnly <TEntity>(this IDbContext dbContext, TEntity entity, params string[] fields)
        {
            Utils.CheckNull(dbContext);
            Utils.CheckNull(entity);
            Utils.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     = entity.GetType();
            TypeDescriptor typeDescriptor = TypeDescriptor.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        memberDescriptor = typeDescriptor.TryGetMappingMemberDescriptor(memberInfo);

                if (memberDescriptor == null)
                {
                    throw new ArgumentException(string.Format("Could not find the member '{0}' from entity.", memberDescriptor.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 (MappingMemberDescriptor primaryKey in typeDescriptor.PrimaryKeys)
            {
                Expression propOrField = Expression.PropertyOrField(parameter, primaryKey.MemberInfo.Name);
                Expression keyValue    = Expression.MakeMemberAccess(entityConstantExp, primaryKey.MemberInfo);
                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(UpdateOnly(dbContext, condition, bindings));
        }
Example #10
0
        public override int Update <TEntity>(Expression <Func <TEntity, bool> > condition, Expression <Func <TEntity, TEntity> > content, string table)
        {
            Utils.CheckNull(condition);
            Utils.CheckNull(content);

            TypeDescriptor typeDescriptor = TypeDescriptor.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;
                MappingMemberDescriptor memberDescriptor = typeDescriptor.TryGetMappingMemberDescriptor(key);

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

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

                SequenceAttribute attr = (SequenceAttribute)memberDescriptor.GetCustomAttribute(typeof(SequenceAttribute));
                if (attr != null)
                {
                    throw new ChloeException(string.Format("Could not update the column '{0}',because it's mapping member has define a sequence.", memberDescriptor.Column.Name));
                }

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

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

            return(this.ExecuteSqlCommand(e));
        }
Example #11
0
        /// <summary>
        /// dbContext.Query&lt;User&gt;().MapTo&lt;User, UserModel&gt;().ToList();
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static IQuery <TModel> MapTo <TEntity, TModel>(this IQuery <TEntity> source)
        {
            /*
             * Usage:
             * dbContext.Query<User>().MapTo<User, UserModel>().ToList();
             */

            /*
             * 根据 TEntity 与 TModel 属性对应关系构建 selector 表达式树,最后调用 Select() 方法
             * dbContext.Query<User>().Select(a => new UserModel() { Id = a.Id, Name = a.Name });
             * ps: 只支持简单的映射,不支持复杂的对应关系
             */

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

            Type           modelType                = typeof(TModel);
            TypeDescriptor typeDescriptor           = TypeDescriptor.GetDescriptor(typeof(TEntity));
            var            mappingMemberDescriptors = typeDescriptor.MappingMemberDescriptors.Select(a => a.Value).ToDictionary(a => a.MemberInfo.Name, a => a);

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

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

                MappingMemberDescriptor mapMemberDescriptor;
                if (mappingMemberDescriptors.TryGetValue(prop.Name, out mapMemberDescriptor) == false)
                {
                    continue;
                }

                Expression sourceMemberAccess = Expression.MakeMemberAccess(parameter, mapMemberDescriptor.MemberInfo);
                if (prop.PropertyType != mapMemberDescriptor.MemberInfoType)
                {
                    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);
            Expression <Func <TEntity, TModel> > selector = Expression.Lambda <Func <TEntity, TModel> >(selectorBody, parameter);

            return(source.Select(selector));
        }
Example #12
0
        /// <summary>
        /// 增加
        /// </summary>
        /// <param name="body">() => new User() { Name = "lu", Age = 18, Gender = Gender.Man, CityId = 1, OpTime = DateTime.Now }</param>
        /// <returns></returns>
        public string Add(Expression <Func <TEntity> > body)
        {
            Checks.NotNull(body, "body");

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



            Dictionary <MemberInfo, Expression> insertColumns = InitMemberExtractor.Extract(body);

            DbInsertExpression e = new DbInsertExpression(typeDescriptor.Table);

            string keyVal = null;

            foreach (var kv in insertColumns)
            {
                MemberInfo key = kv.Key;
                MappingMemberDescriptor memberDescriptor = typeDescriptor.TryGetMappingMemberDescriptor(key);

                //如果是主键
                if (memberDescriptor.SZColumnAttribute.IsKey)
                {
                    object val = ExpressionEvaluator.Evaluate(kv.Value);
                    if (val == null || string.IsNullOrEmpty(val.ToString()))
                    {
                        val    = GetNewKey();
                        keyVal = val.ToString();
                        e.InsertColumns.Add(memberDescriptor.Column, DbExpression.Parameter(keyVal));
                        continue;
                    }
                }
                //如果是添加或修改时间
                if (memberDescriptor.SZColumnAttribute.IsAddTime || memberDescriptor.SZColumnAttribute.IsEditTime)
                {
                    object val = ExpressionEvaluator.Evaluate(kv.Value);
                    val = DateTime.Now;
                    e.InsertColumns.Add(memberDescriptor.Column, DbExpression.Parameter(keyVal));
                    continue;
                }
                e.InsertColumns.Add(memberDescriptor.Column, typeDescriptor.Visitor.Visit(kv.Value));
            }


            IDbExpressionTranslator translator = this.DbContext._dbContextServiceProvider.CreateDbExpressionTranslator();
            List <DbParam>          parameters;
            string sql = translator.Translate(e, out parameters);

            this.DbContext.ExecuteNoQuery(sql, parameters.ToArray());
            return(keyVal);
        }
Example #13
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)
        {
            Utils.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           = TypeDescriptor.GetDescriptor(entityType);
            var            mappingMemberDescriptors = typeDescriptor.MappingMemberDescriptors.Select(a => a.Value).ToList();

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

            foreach (var mappingMemberDescriptor in mappingMemberDescriptors)
            {
                if (fields.Any(a => a == mappingMemberDescriptor.MemberInfo.Name))
                {
                    continue;
                }

                Expression       sourceMemberAccess = Expression.MakeMemberAccess(parameter, mappingMemberDescriptor.MemberInfo);
                MemberAssignment bind = Expression.Bind(mappingMemberDescriptor.MemberInfo, 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));
        }
Example #14
0
        /// <summary>
        /// 序列化对象为键值对
        /// </summary>
        /// <param name="name">对象名称</param>
        /// <param name="obj">对象实例</param>
        /// <param name="options">选项</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns></returns>
        protected virtual IEnumerable <KeyValuePair <string, string> > Serialize(
            string name,
            object obj,
            FormatOptions options)
        {
            if (options == null)
            {
                options = new FormatOptions();
            }

            var type       = obj == null ? null : obj.GetType();
            var descriptor = TypeDescriptor.GetDescriptor(type);

            if (descriptor == null || descriptor.IsSimpleType == true)
            {
                return(new[] { this.SerializeAsSimple(name, obj, options) });
            }

            if (type == typeof(KeyValuePair <string, string>))
            {
                var kv = (KeyValuePair <string, string>)obj;
                return(new[] { this.SerializeAsSimple(kv.Key, kv.Value, options) });
            }

            if (type == typeof(KeyValuePair <string, object>))
            {
                var kv = (KeyValuePair <string, object>)obj;
                return(new[] { this.SerializeAsSimple(kv.Key, kv.Value, options) });
            }

            if (descriptor.IsEnumerableKeyValueOfString == true)
            {
                var dic = obj as IEnumerable <KeyValuePair <string, string> >;
                return(this.SerializeAsDictionary <string>(dic, options));
            }

            if (descriptor.IsEnumerableKeyValueOfObject == true)
            {
                var dic = obj as IEnumerable <KeyValuePair <string, object> >;
                return(this.SerializeAsDictionary <object>(dic, options));
            }

            if (descriptor.IsEnumerable == true)
            {
                var enumerable = obj as IEnumerable;
                return(this.SerializeAsEnumerable(name, enumerable, options));
            }

            return(this.SerializeAsComplex(obj, options));
        }
Example #15
0
        static ResultElement CreateResultElement(Type type, string explicitTableName)
        {
            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();

            TypeDescriptor typeDescriptor = TypeDescriptor.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);

            ConstructorInfo constructor = typeDescriptor.EntityType.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 (MappingMemberDescriptor item in typeDescriptor.MappingMemberDescriptors.Values)
            {
                DbColumnAccessExpression columnAccessExpression = new DbColumnAccessExpression(table, item.Column);

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

            resultElement.MappingObjectExpression = moe;

            return(resultElement);
        }
Example #16
0
        /// <summary>
        /// 条件删除
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public int Remove(Expression <Func <TEntity, bool> > condition)
        {
            Checks.NotNull(condition, "condition");

            TypeDescriptor typeDescriptor = TypeDescriptor.GetDescriptor(typeof(TEntity));
            DbExpression   conditionExp   = typeDescriptor.Visitor.VisitFilterPredicate(condition);

            DbDeleteExpression e = new DbDeleteExpression(typeDescriptor.Table, conditionExp);

            IDbExpressionTranslator translator = this.DbContext._dbContextServiceProvider.CreateDbExpressionTranslator();
            List <DbParam>          parameters;
            string sql = translator.Translate(e, out parameters);

            return(this.DbContext.ExecuteNoQuery(sql, parameters.ToArray()));
        }
Example #17
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 = TypeDescriptor.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);
        }
Example #18
0
        public virtual T Insert <T>(T entity)
        {
            Utils.CheckNull(entity);

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

            EnsureMappingTypeHasPrimaryKey(typeDescriptor);

            MappingMemberDescriptor keyMemberDescriptor = typeDescriptor.PrimaryKey;
            MemberInfo keyMember = typeDescriptor.PrimaryKey.MemberInfo;

            object keyValue = null;

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

            foreach (var kv in typeDescriptor.MappingMemberDescriptors)
            {
                MemberInfo member = kv.Key;
                MappingMemberDescriptor memberDescriptor = kv.Value;

                var val = memberDescriptor.GetValue(entity);

                if (memberDescriptor == keyMemberDescriptor)
                {
                    keyValue = val;
                }

                DbExpression valExp = DbExpression.Parameter(val, memberDescriptor.MemberInfoType);
                insertColumns.Add(memberDescriptor, valExp);
            }

            //主键为空并且主键又不是自增列
            if (keyValue == null)
            {
                throw new ChloeException(string.Format("The primary key '{0}' could not be null.", keyMemberDescriptor.MemberInfo.Name));
            }

            DbInsertExpression e = new DbInsertExpression(typeDescriptor.Table);

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

            this.ExecuteSqlCommand(e);
            return(entity);
        }
Example #19
0
        public override JoinQueryResult Visit(RootQueryExpression exp)
        {
            Type           type           = exp.ElementType;
            TypeDescriptor typeDescriptor = TypeDescriptor.GetDescriptor(type);

            string  explicitTableName = exp.ExplicitTable;
            DbTable dbTable           = typeDescriptor.Table;

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

            DbTableSegment          tableSeg = CreateTableExpression(dbTable, alias);
            MappingObjectExpression moe      = new MappingObjectExpression(typeDescriptor.EntityType.GetConstructor(Type.EmptyTypes));

            DbTable table = new DbTable(alias);

            foreach (MappingMemberDescriptor item in typeDescriptor.MappingMemberDescriptors.Values)
            {
                DbColumnAccessExpression columnAccessExpression = new DbColumnAccessExpression(table, item.Column);
                moe.AddMemberExpression(item.MemberInfo, columnAccessExpression);

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

            //TODO 解析 on 条件表达式
            DbExpression condition = null;
            List <IMappingObjectExpression> moeList = new List <IMappingObjectExpression>(this._moeList.Count + 1);

            moeList.AddRange(this._moeList);
            moeList.Add(moe);
            condition = GeneralExpressionVisitor.ParseLambda(this._conditionExpression, moeList);

            DbJoinTableExpression joinTable = new DbJoinTableExpression(this._joinType, tableSeg, condition);

            JoinQueryResult result = new JoinQueryResult();

            result.MappingObjectExpression = moe;
            result.JoinTable = joinTable;

            return(result);
        }
Example #20
0
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public TEntity Add(TEntity entity)
        {
            Checks.NotNull(entity, "entity");

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

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

            foreach (var kv in typeDescriptor.MappingMemberDescriptors)
            {
                MemberInfo member = kv.Key;
                MappingMemberDescriptor memberDescriptor = kv.Value;

                object val = memberDescriptor.GetValue(entity);

                if (memberDescriptor.SZColumnAttribute.IsKey)
                {
                    if (val == null || string.IsNullOrEmpty(val.ToString()))
                    {
                        val = GetNewKey();
                        memberDescriptor.SetValue(entity, val);
                    }
                }
                if (memberDescriptor.SZColumnAttribute.IsAddTime || memberDescriptor.SZColumnAttribute.IsEditTime)
                {
                    val = DateTime.Now;
                    memberDescriptor.SetValue(entity, val);
                }
                DbExpression valExp = DbExpression.Parameter(val, memberDescriptor.MemberInfoType);
                insertColumns.Add(memberDescriptor, valExp);
            }

            DbInsertExpression e = new DbInsertExpression(typeDescriptor.Table);

            foreach (var kv in insertColumns)
            {
                e.InsertColumns.Add(kv.Key.Column, kv.Value);
            }
            IDbExpressionTranslator translator = this.DbContext.DatabaseProvider.CreateDbExpressionTranslator();
            List <DbParam>          parameters;
            string sql = translator.Translate(e, out parameters);

            this.DbContext.ExecuteNoQuery(sql, parameters.ToArray());

            return(entity);
        }
        /// <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 = TypeDescriptor.GetDescriptor(entityType);

            /* 设置 主键=guid */
            if (typeDescriptor.PrimaryKeys.Count < 2) /* 只有无主键或单一主键的时候 */
            {
                MappingMemberDescriptor primaryKeyDescriptor = typeDescriptor.PrimaryKeys.FirstOrDefault();
                if (primaryKeyDescriptor != null && primaryKeyDescriptor.IsAutoIncrement == false)
                {
                    var keyValue = primaryKeyDescriptor.GetValue(entity);
                    if (keyValue.IsDefaultValueOfType(primaryKeyDescriptor.MemberInfoType) || string.Empty.Equals(keyValue))
                    {
                        /* 如果未设置主键值,则自动设置为 guid */
                        if (primaryKeyDescriptor.MemberInfoType == typeof(string))
                        {
                            primaryKeyDescriptor.SetValue(entity, IdHelper.CreateGuid());
                        }
                        else if (primaryKeyDescriptor.MemberInfoType.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));
        }
Example #22
0
        static Expression <Func <TEntity, bool> > BuildPredicate <TEntity>(object key)
        {
            Utils.CheckNull(key);

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

            EnsureEntityHasPrimaryKey(typeDescriptor);

            ParameterExpression parameter   = Expression.Parameter(entityType, "a");
            Expression          propOrField = Expression.PropertyOrField(parameter, typeDescriptor.PrimaryKey.MemberInfo.Name);
            Expression          keyValue    = Chloe.Extensions.ExpressionExtension.MakeWrapperAccess(key, typeDescriptor.PrimaryKey.MemberInfoType);
            Expression          lambdaBody  = Expression.Equal(propOrField, keyValue);

            Expression <Func <TEntity, bool> > predicate = Expression.Lambda <Func <TEntity, bool> >(lambdaBody, parameter);

            return(predicate);
        }
Example #23
0
        public virtual int Delete <TEntity>(Expression <Func <TEntity, bool> > condition, string table)
        {
            Utils.CheckNull(condition);

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

            DbTable explicitDbTable = null;

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

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

            return(this.ExecuteSqlCommand(e));
        }
Example #24
0
        public static Expression <Func <TEntity, bool> > BuildPredicate <TEntity>(object key)
        {
            Checks.NotNull(key, "key");
            Type           entityType     = typeof(TEntity);
            TypeDescriptor typeDescriptor = TypeDescriptor.GetDescriptor(entityType);

            if (typeDescriptor.PrimaryKey == null)
            {
                throw new SZORMException("表没有定义主键.");
            }
            ParameterExpression parameter   = Expression.Parameter(entityType, "a");
            Expression          propOrField = Expression.PropertyOrField(parameter, typeDescriptor.PrimaryKey.MemberInfo.Name);
            Expression          keyValue    = ExpressionExtension.MakeWrapperAccess(key, typeDescriptor.PrimaryKey.MemberInfoType);
            Expression          lambdaBody  = Expression.Equal(propOrField, keyValue);

            Expression <Func <TEntity, bool> > predicate = Expression.Lambda <Func <TEntity, bool> >(lambdaBody, parameter);

            return(predicate);
        }
Example #25
0
        public virtual int Update <TEntity>(Expression <Func <TEntity, bool> > condition, Expression <Func <TEntity, TEntity> > body)
        {
            Utils.CheckNull(condition);
            Utils.CheckNull(body);

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

            Dictionary <MemberInfo, Expression> updateColumns = InitMemberExtractor.Extract(body);
            DbExpression conditionExp = typeDescriptor.Visitor.VisitFilterPredicate(condition);

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

            foreach (var kv in updateColumns)
            {
                MemberInfo key = kv.Key;
                MappingMemberDescriptor memberDescriptor = typeDescriptor.TryGetMappingMemberDescriptor(key);

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

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

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

                e.UpdateColumns.Add(memberDescriptor.Column, typeDescriptor.Visitor.Visit(kv.Value));
            }

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

            return(this.ExecuteSqlCommand(e));
        }
        /// <summary>
        /// 序列化对象为键值对
        /// </summary>
        /// <param name="name">对象名称</param>
        /// <param name="obj">对象实例</param>
        /// <param name="options">选项</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns></returns>
        protected virtual IEnumerable <KeyValuePair <string, string> > Serialize(
            string name,
            object obj,
            FormatOptions options)
        {
            if (options == null)
            {
                options = new FormatOptions();
            }

            var type    = obj == null ? null : obj.GetType();
            var context = new ConvertContext
            {
                Name       = name,
                Value      = obj,
                Options    = options,
                Descriptor = TypeDescriptor.GetDescriptor(type)
            };

            return(this.linkedList.First.Value.Invoke(context));
        }
Example #27
0
        static Expression <Func <TEntity, bool> > BuildPredicate <TEntity>(object key)
        {
            Utils.CheckNull(key);

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

            if (!typeDescriptor.HasPrimaryKey())
            {
                throw new ChloeException(string.Format("The entity type '{0}' does not define a primary key.", typeDescriptor.EntityType.FullName));
            }

            ParameterExpression parameter   = Expression.Parameter(entityType, "a");
            Expression          propOrField = Expression.PropertyOrField(parameter, typeDescriptor.PrimaryKey.MemberInfo.Name);
            Expression          keyValue    = Utils.MakeWrapperAccess(key, typeDescriptor.PrimaryKey.MemberInfoType);
            Expression          lambdaBody  = Expression.Equal(propOrField, keyValue);

            Expression <Func <TEntity, bool> > predicate = Expression.Lambda <Func <TEntity, bool> >(lambdaBody, parameter);

            return(predicate);
        }
Example #28
0
        public virtual int Delete <TEntity>(TEntity entity, string table)
        {
            Utils.CheckNull(entity);

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

            EnsureEntityHasPrimaryKey(typeDescriptor);

            Dictionary <MappingMemberDescriptor, object> keyValueMap = new Dictionary <MappingMemberDescriptor, object>();

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

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

            return(this.ExecuteSqlCommand(e));
        }
Example #29
0
        public override int Update <T>(Expression <Func <T, T> > body, Expression <Func <T, bool> > condition)
        {
            Utils.CheckNull(body);
            Utils.CheckNull(condition);

            TypeDescriptor typeDescriptor = TypeDescriptor.GetDescriptor(typeof(T));

            Dictionary <MemberInfo, Expression> updateColumns = InitMemberExtractor.Extract(body);
            var conditionExp = typeDescriptor.Visitor.VisitFilterPredicate(condition);

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

            foreach (var kv in updateColumns)
            {
                MemberInfo key = kv.Key;
                MappingMemberDescriptor memberDescriptor = typeDescriptor.TryGetMappingMemberDescriptor(key);

                if (memberDescriptor == null)
                {
                    throw new Exception(string.Format("成员 {0} 未映射任何列", key.Name));
                }

                if (memberDescriptor.IsPrimaryKey)
                {
                    throw new Exception(string.Format("无法对主键 '{0}' 进行更新", memberDescriptor.Column.Name));
                }

                AutoIncrementAttribute attr = (AutoIncrementAttribute)memberDescriptor.GetCustomAttribute(typeof(AutoIncrementAttribute));
                if (attr != null)
                {
                    throw new Exception(string.Format("无法对自增长列 '{0}' 进行更新", memberDescriptor.Column.Name));
                }

                e.UpdateColumns.Add(memberDescriptor.Column, typeDescriptor.Visitor.Visit(kv.Value));
            }

            return(this.ExecuteSqlCommand(e));
        }
        /// <summary>
        /// 序列化对象为键值对
        /// </summary>
        /// <param name="name">对象名称</param>
        /// <param name="obj">对象实例</param>
        /// <param name="options">选项</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns></returns>
        public IEnumerable <KeyValuePair <string, string> > Serialize(string name, object obj, FormatOptions options)
        {
            if (options == null)
            {
                options = new FormatOptions();
            }

            var type       = obj == null ? null : obj.GetType();
            var descriptor = TypeDescriptor.GetDescriptor(type);

            if (descriptor == null || descriptor.IsSimpleType == true)
            {
                var kv = this.FormatAsSimple(name, obj, options);
                return(new[] { kv });
            }

            if (descriptor.IsDictionaryOfString == true)
            {
                var dic = obj as IDictionary <string, string>;
                return(this.FormatAsDictionary <string>(dic, options));
            }

            if (descriptor.IsDictionaryOfObject == true)
            {
                var dic = obj as IDictionary <string, object>;
                return(this.FormatAsDictionary <object>(dic, options));
            }

            if (descriptor.IsEnumerable == true)
            {
                var enumerable = obj as IEnumerable;
                return(this.ForamtAsEnumerable(name, enumerable, options));
            }

            return(this.FormatAsComplex(obj, options));
        }