예제 #1
0
        public override int Update <TEntity>(TEntity entity, string table)
        {
            PublicHelper.CheckNull(entity);

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

            PublicHelper.EnsureHasPrimaryKey(typeDescriptor);

            Dictionary <PropertyDescriptor, object> keyValueMap = PrimaryKeyHelper.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 = PrimaryKeyHelper.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.ExecuteNonQuery(e);

            if (entityState != null)
            {
                entityState.Refresh();
            }
            return(ret);
        }
예제 #2
0
        protected virtual async Task <TEntity> Insert <TEntity>(TEntity entity, string table, bool @async)
        {
            PublicHelper.CheckNull(entity);

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

            Dictionary <PrimitivePropertyDescriptor, object> keyValueMap = PrimaryKeyHelper.CreateKeyValueMap(typeDescriptor);

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

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

                object val = propertyDescriptor.GetValue(entity);

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

                PublicHelper.NotNullCheck(propertyDescriptor, val);

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

            PrimitivePropertyDescriptor nullValueKey = keyValueMap.Where(a => a.Value == null && !a.Key.IsAutoIncrement).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 = PublicHelper.CreateDbTable(typeDescriptor, table);
            DbInsertExpression e       = new DbInsertExpression(dbTable);

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

            PrimitivePropertyDescriptor autoIncrementPropertyDescriptor = typeDescriptor.AutoIncrement;

            if (autoIncrementPropertyDescriptor == null)
            {
                await this.ExecuteNonQuery(e, @async);

                return(entity);
            }

            IDbExpressionTranslator translator    = this.DatabaseProvider.CreateDbExpressionTranslator();
            DbCommandInfo           dbCommandInfo = translator.Translate(e);

            dbCommandInfo.CommandText = string.Concat(dbCommandInfo.CommandText, ";", this.GetSelectLastInsertIdClause());

            //SELECT @@IDENTITY 返回的是 decimal 类型
            object retIdentity = await this.ExecuteScalar(dbCommandInfo, @async);

            if (retIdentity == null || retIdentity == DBNull.Value)
            {
                throw new ChloeException("Unable to get the identity value.");
            }

            retIdentity = PublicHelper.ConvertObjectType(retIdentity, autoIncrementPropertyDescriptor.PropertyType);
            autoIncrementPropertyDescriptor.SetValue(entity, retIdentity);
            return(entity);
        }
예제 #3
0
        public override TEntity Insert <TEntity>(TEntity entity, string table)
        {
            PublicHelper.CheckNull(entity);

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

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

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

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

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

                object val = propertyDescriptor.GetValue(entity);

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

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

            PropertyDescriptor nullValueKey = keyValueMap.Where(a => a.Value == null && !a.Key.IsAutoIncrement).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 insertExp = new DbInsertExpression(dbTable);

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

            List <Action <TEntity, IDataReader> > mappers = new List <Action <TEntity, IDataReader> >();

            foreach (var item in typeDescriptor.PropertyDescriptors.Where(a => a.IsAutoIncrement || a.HasSequence()))
            {
                mappers.Add(GetMapper <TEntity>(item, insertExp.Returns.Count));
                insertExp.Returns.Add(item.Column);
            }

            if (mappers.Count == 0)
            {
                this.ExecuteNonQuery(insertExp);
                return(entity);
            }

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

            IDataReader dataReader = this.Session.ExecuteReader(sql, parameters.ToArray());

            using (dataReader)
            {
                dataReader.Read();
                foreach (var mapper in mappers)
                {
                    mapper(entity, dataReader);
                }
            }

            return(entity);
        }
예제 #4
0
        public override int Update <TEntity>(TEntity entity, string table)
        {
            PublicHelper.CheckNull(entity);

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

            PublicHelper.EnsureHasPrimaryKey(typeDescriptor);

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

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

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

                if (propertyDescriptor.IsAutoIncrement)
                {
                    continue;
                }

                if (propertyDescriptor.IsTimestamp())
                {
                    timestampProperty = propertyDescriptor;
                    timestampValue    = propertyDescriptor.GetValue(entity);
                    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);

            if (timestampValue != null)
            {
                keyValueMap[timestampProperty] = timestampValue;
            }

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

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

            int rowsAffected = 0;

            if (timestampValue == null)
            {
                rowsAffected = this.ExecuteNonQuery(e);
                if (entityState != null)
                {
                    entityState.Refresh();
                }
                return(rowsAffected);
            }

            List <Action <TEntity, IDataReader> > mappers = new List <Action <TEntity, IDataReader> >();

            mappers.Add(GetMapper <TEntity>(timestampProperty, e.Returns.Count));
            e.Returns.Add(timestampProperty.Column);

            IDataReader dataReader = this.ExecuteReader(e);

            using (dataReader)
            {
                while (dataReader.Read())
                {
                    rowsAffected++;
                    foreach (var mapper in mappers)
                    {
                        mapper(entity, dataReader);
                    }
                }
            }

            return(rowsAffected);
        }
예제 #5
0
        protected override async Task <TEntity> Insert <TEntity>(TEntity entity, string table, bool @async)
        {
            PublicHelper.CheckNull(entity);

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

            DbTable dbTable = PublicHelper.CreateDbTable(typeDescriptor, table);

            Dictionary <PrimitivePropertyDescriptor, object> keyValueMap = PrimaryKeyHelper.CreateKeyValueMap(typeDescriptor);

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

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

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

                object val = propertyDescriptor.GetValue(entity);

                PublicHelper.NotNullCheck(propertyDescriptor, val);

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

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

            PrimitivePropertyDescriptor nullValueKey = keyValueMap.Where(a => a.Value == null && !a.Key.IsAutoIncrement).Select(a => a.Key).FirstOrDefault();

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

            DbInsertExpression insertExp = new DbInsertExpression(dbTable);

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

            if (outputColumns.Count == 0)
            {
                await this.ExecuteNonQuery(insertExp, @async);

                return(entity);
            }

            List <Action <TEntity, IDataReader> > mappers = new List <Action <TEntity, IDataReader> >();
            IDbExpressionTranslator translator            = this.DatabaseProvider.CreateDbExpressionTranslator();
            DbCommandInfo           dbCommandInfo;

            if (outputColumns.Count == 1 && outputColumns[0].IsAutoIncrement)
            {
                dbCommandInfo = translator.Translate(insertExp);

                /* 自增 id 不能用 output  inserted.Id 输出,因为如果表设置了触发器的话会报错 */
                dbCommandInfo.CommandText = string.Concat(dbCommandInfo.CommandText, ";", this.GetSelectLastInsertIdClause());
                mappers.Add(GetMapper <TEntity>(outputColumns[0], 0));
            }
            else
            {
                foreach (PrimitivePropertyDescriptor outputColumn in outputColumns)
                {
                    mappers.Add(GetMapper <TEntity>(outputColumn, insertExp.Returns.Count));
                    insertExp.Returns.Add(outputColumn.Column);
                }

                dbCommandInfo = translator.Translate(insertExp);
            }

            IDataReader dataReader = this.Session.ExecuteReader(dbCommandInfo.CommandText, dbCommandInfo.GetParameters());

            using (dataReader)
            {
                dataReader.Read();
                foreach (var mapper in mappers)
                {
                    mapper(entity, dataReader);
                }
            }

            return(entity);
        }