示例#1
0
文件: DbContext.cs 项目: softxa/Chloe
        public virtual int Update <TEntity>(TEntity entity, string table)
        {
            Utils.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 (propertyDescriptor.IsPrimaryKey)
                {
                    keyValueMap[propertyDescriptor] = propertyDescriptor.GetValue(entity);
                    continue;
                }

                if (propertyDescriptor.IsAutoIncrement)
                {
                    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);
        }
示例#2
0
文件: DbContext.cs 项目: softxa/Chloe
        public virtual int Delete <TEntity>(TEntity entity, string table)
        {
            Utils.CheckNull(entity);

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

            PublicHelper.EnsureHasPrimaryKey(typeDescriptor);

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

            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);
            DbExpression       conditionExp = MakeCondition(keyValueMap, dbTable);
            DbDeleteExpression e            = new DbDeleteExpression(dbTable, conditionExp);

            return(this.ExecuteSqlCommand(e));
        }
示例#3
0
        protected virtual async Task <int> Delete <TEntity>(TEntity entity, string table, bool @async)
        {
            PublicHelper.CheckNull(entity);

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

            PublicHelper.EnsureHasPrimaryKey(typeDescriptor);

            PairList <PrimitivePropertyDescriptor, object> keyValues = new PairList <PrimitivePropertyDescriptor, object>(typeDescriptor.PrimaryKeys.Count);

            foreach (PrimitivePropertyDescriptor keyPropertyDescriptor in typeDescriptor.PrimaryKeys)
            {
                object keyValue = keyPropertyDescriptor.GetValue(entity);
                PrimaryKeyHelper.KeyValueNotNull(keyPropertyDescriptor, keyValue);
                keyValues.Add(keyPropertyDescriptor, keyValue);
            }

            if (typeDescriptor.HasRowVersion())
            {
                var rowVersionValue = typeDescriptor.RowVersion.GetValue(entity);
                keyValues.Add(typeDescriptor.RowVersion, rowVersionValue);
            }

            DbTable            dbTable      = PublicHelper.CreateDbTable(typeDescriptor, table);
            DbExpression       conditionExp = PublicHelper.MakeCondition(keyValues, dbTable);
            DbDeleteExpression e            = new DbDeleteExpression(dbTable, conditionExp);

            int rowsAffected = await this.ExecuteNonQuery(e, @async);

            if (typeDescriptor.HasRowVersion())
            {
                PublicHelper.CauseErrorIfOptimisticUpdateFailed(rowsAffected);
            }

            return(rowsAffected);
        }
示例#4
0
        protected virtual async Task <int> Update <TEntity>(TEntity entity, string table, bool @async)
        {
            PublicHelper.CheckNull(entity);

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

            PublicHelper.EnsureHasPrimaryKey(typeDescriptor);

            PairList <PrimitivePropertyDescriptor, object> keyValues = new PairList <PrimitivePropertyDescriptor, object>(typeDescriptor.PrimaryKeys.Count);

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

            foreach (PrimitivePropertyDescriptor propertyDescriptor in typeDescriptor.PrimitivePropertyDescriptors)
            {
                if (propertyDescriptor.IsPrimaryKey)
                {
                    var keyValue = propertyDescriptor.GetValue(entity);
                    PrimaryKeyHelper.KeyValueNotNull(propertyDescriptor, keyValue);
                    keyValues.Add(propertyDescriptor, keyValue);
                    continue;
                }

                if (propertyDescriptor.IsAutoIncrement || propertyDescriptor.HasSequence() || propertyDescriptor.IsRowVersion)
                {
                    continue;
                }

                object val = propertyDescriptor.GetValue(entity);
                PublicHelper.NotNullCheck(propertyDescriptor, val);

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

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

            object rowVersionNewValue = null;

            if (typeDescriptor.HasRowVersion())
            {
                var rowVersionDescriptor = typeDescriptor.RowVersion;
                var rowVersionOldValue   = rowVersionDescriptor.GetValue(entity);
                rowVersionNewValue = PublicHelper.IncreaseRowVersionNumber(rowVersionOldValue);
                updateColumns.Add(rowVersionDescriptor, DbExpression.Parameter(rowVersionNewValue, rowVersionDescriptor.PropertyType, rowVersionDescriptor.Column.DbType));
                keyValues.Add(rowVersionDescriptor, rowVersionOldValue);
            }

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

            DbTable            dbTable      = PublicHelper.CreateDbTable(typeDescriptor, table);
            DbExpression       conditionExp = PublicHelper.MakeCondition(keyValues, dbTable);
            DbUpdateExpression e            = new DbUpdateExpression(dbTable, conditionExp);

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

            int rowsAffected = await this.ExecuteNonQuery(e, @async);

            if (typeDescriptor.HasRowVersion())
            {
                PublicHelper.CauseErrorIfOptimisticUpdateFailed(rowsAffected);
                typeDescriptor.RowVersion.SetValue(entity, rowVersionNewValue);
            }

            if (entityState != null)
            {
                entityState.Refresh();
            }

            return(rowsAffected);
        }
示例#5
0
        static Expression <Func <TEntity, bool> > BuildCondition <TEntity>(object key)
        {
            /*
             * key:
             * 如果实体是单一主键,可以传入的 key 与主键属性类型相同的值,亦可以传一个包含了与实体主键类型相同的属性的对象,如:new { Id = 1 }
             * 如果实体是多主键,则传入的 key 须是包含了与实体主键类型相同的属性的对象,如:new { Key1 = "1", Key2 = "2" }
             */

            Utils.CheckNull(key);

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

            PublicHelper.EnsureHasPrimaryKey(typeDescriptor);

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

            Type keyType = key.GetType();

            if (typeDescriptor.PrimaryKeys.Count == 1 && MappingTypeSystem.IsMappingType(keyType))
            {
                /* a => a.Key == key */

                PropertyDescriptor keyDescriptor = typeDescriptor.PrimaryKeys[0];
                Expression         propOrField   = Expression.PropertyOrField(parameter, keyDescriptor.Property.Name);
                Expression         wrappedValue  = ExpressionExtension.MakeWrapperAccess(key, keyDescriptor.PropertyType);
                conditionBody = Expression.Equal(propOrField, wrappedValue);
            }
            else
            {
                /*
                 * key: new { Key1 = "1", Key2 = "2" }
                 */

                /* a => a.Key1 == key.Key1 && a.Key2 == key.Key2 */

                Type keyObjectType = keyType;
                ConstantExpression keyConstantExp = Expression.Constant(key);
                if (keyObjectType == entityType)
                {
                    foreach (PropertyDescriptor primaryKey in typeDescriptor.PrimaryKeys)
                    {
                        Expression propOrField = Expression.PropertyOrField(parameter, primaryKey.Property.Name);
                        Expression keyValue    = Expression.MakeMemberAccess(keyConstantExp, primaryKey.Property);
                        Expression e           = Expression.Equal(propOrField, keyValue);
                        conditionBody = conditionBody == null ? e : Expression.AndAlso(conditionBody, e);
                    }
                }
                else
                {
                    for (int i = 0; i < typeDescriptor.PrimaryKeys.Count; i++)
                    {
                        PropertyDescriptor keyPropertyDescriptor = typeDescriptor.PrimaryKeys[i];
                        MemberInfo         keyMember             = keyPropertyDescriptor.Property;
                        MemberInfo         inputKeyMember        = keyObjectType.GetMember(keyMember.Name).FirstOrDefault();
                        if (inputKeyMember == null)
                        {
                            throw new ArgumentException(string.Format("The input object does not define property for key '{0}'.", keyMember.Name));
                        }

                        Expression propOrField = Expression.PropertyOrField(parameter, keyMember.Name);
                        Expression keyValueExp = Expression.MakeMemberAccess(keyConstantExp, inputKeyMember);

                        Type keyMemberType = keyMember.GetMemberType();
                        if (inputKeyMember.GetMemberType() != keyMemberType)
                        {
                            keyValueExp = Expression.Convert(keyValueExp, keyMemberType);
                        }
                        Expression e = Expression.Equal(propOrField, keyValueExp);
                        conditionBody = conditionBody == null ? e : Expression.AndAlso(conditionBody, e);
                    }
                }
            }

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

            return(condition);
        }