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); }
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)); }
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); }
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); }
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); }