public override bool IsModified(MappingEntity entity, object instance, object original) { if (base.IsModified(entity, instance, original)) return true; // need to check nested entities too foreach (var mi in this.GetMappedMembers(entity)) { if (this.IsNestedEntity(entity, mi)) { MappingEntity nested = this.GetRelatedEntity(entity, mi); if (this.IsModified(nested, mi.GetValue(instance), mi.GetValue(original))) return true; } } return false; }
public override object CloneEntity(MappingEntity entity, object instance) { object clone = base.CloneEntity(entity, instance); // need to clone nested entities too foreach (var mi in this.GetMappedMembers(entity)) { if (this.IsNestedEntity(entity, mi)) { MappingEntity nested = this.GetRelatedEntity(entity, mi); var nestedValue = mi.GetValue(instance); if (nestedValue != null) { var nestedClone = this.CloneEntity(nested, mi.GetValue(instance)); mi.SetValue(clone, nestedClone); } } } return clone; }
// make a variable declaration / initialization for dependent generated values private CommandExpression GetDependentGeneratedVariableDeclaration(MappingEntity entity, MappingTable table, List<MemberInfo> members, Expression instance, Dictionary<MemberInfo, Expression> map) { // first make command that retrieves the generated ids if any DeclarationCommand genIdCommand = null; var generatedIds = this.mapping.GetMappedMembers(entity).Where(m => this.mapping.IsPrimaryKey(entity, m) && this.mapping.IsIdentity(entity, m)).ToList(); if (generatedIds.Count > 0) { genIdCommand = this.GetGeneratedIdCommand(entity, members, map); // if that's all there is then just return the generated ids if (members.Count == generatedIds.Count) { return genIdCommand; } } // next make command that retrieves the generated members // only consider members that were not generated ids members = members.Except(generatedIds).ToList(); var tableAlias = new TableAlias(); var tex = new TableExpression(tableAlias, entity, this.mapping.GetTableName(table)); Expression where = null; if (generatedIds.Count > 0) { where = generatedIds.Select((m, i) => this.GetMemberExpression(tex, entity, m).Equal(map[m]) ).Aggregate((x, y) => x.And(y)); } else { where = this.GetIdentityCheck(tex, entity, instance); } TableAlias selectAlias = new TableAlias(); var columns = new List<ColumnDeclaration>(); var variables = new List<VariableDeclaration>(); foreach (var mi in members) { ColumnExpression col = (ColumnExpression)this.GetMemberExpression(tex, entity, mi); columns.Add(new ColumnDeclaration(this.mapping.GetColumnName(entity, mi), col, col.QueryType)); ColumnExpression vcol = new ColumnExpression(col.Type, col.QueryType, selectAlias, col.Name); variables.Add(new VariableDeclaration(mi.Name, col.QueryType, vcol)); map.Add(mi, new VariableExpression(mi.Name, col.Type, col.QueryType)); } var genMembersCommand = new DeclarationCommand(variables, new SelectExpression(selectAlias, columns, tex, where)); if (genIdCommand != null) { return new BlockCommand(genIdCommand, genMembersCommand); } return genMembersCommand; }
/// <summary> /// Get an expression that represents the delete operation for the specified instance. /// </summary> /// <param name="entity"></param> /// <param name="instance"></param> /// <param name="deleteCheck"></param> /// <returns></returns> public abstract Expression GetDeleteExpression(MappingEntity entity, Expression instance, LambdaExpression deleteCheck);
/// <summary> /// Get an expression that represents the update operation for the specified instance. /// </summary> /// <param name="entity">The entity.</param> /// <param name="instance">The instance.</param> /// <param name="updateCheck">The update check.</param> /// <param name="selector">The selector.</param> /// <param name="indeedColumns">The indeed columns.</param> /// <param name="else">The @else.</param> /// <returns></returns> public abstract Expression GetUpdateExpression(MappingEntity entity, Expression instance, LambdaExpression updateCheck, LambdaExpression selector, ColumnIndeedExpression indeedColumns, Expression @else);
/// <summary> /// Get an expression that represents the insert operation for the specified instance. /// </summary> /// <param name="entity"></param> /// <param name="instance">The instance to insert.</param> /// <param name="selector">A lambda expression that computes a return value from the operation.</param> /// <returns></returns> public abstract Expression GetInsertExpression(MappingEntity entity, Expression instance, LambdaExpression selector);
/// <summary> /// Gets an expression that constructs an entity instance relative to a root. /// The root is most often a TableExpression, but may be any other experssion such as /// a ConstantExpression. /// </summary> /// <param name="root"></param> /// <param name="entity"></param> /// <returns></returns> public abstract EntityExpression GetEntityExpression(Expression root, MappingEntity entity);
/// <summary> /// Determines whether the specified entity is modified. /// </summary> /// <param name="entity">The entity.</param> /// <param name="instance">The instance.</param> /// <param name="original">The original.</param> /// <returns> /// <c>true</c> if the specified entity is modified; otherwise, <c>false</c>. /// </returns> public abstract bool IsModified(MappingEntity entity, object instance, object original);
/// <summary> /// Gets the depending entities. /// </summary> /// <param name="entity">The entity.</param> /// <param name="instance">The instance.</param> /// <returns></returns> public abstract IEnumerable<EntityInfo> GetDependingEntities(MappingEntity entity, object instance);
public override Expression GetDeleteExpression(MappingEntity entity, Expression instance, LambdaExpression deleteCheck) { var tables = this.mapping.GetTables(entity); if (tables.Count < 2) { return base.GetDeleteExpression(entity, instance, deleteCheck); } var commands = new List<Expression>(); foreach (var table in this.GetDependencyOrderedTables(entity).Reverse()) { TableExpression tex = new TableExpression(new TableAlias(), entity, this.mapping.GetTableName(table)); var where = this.GetIdentityCheck(tex, entity, instance); commands.Add(new DeleteCommand(tex, where)); } Expression block = new BlockCommand(commands); if (deleteCheck != null) { var test = this.GetEntityStateTest(entity, instance, deleteCheck); return new IFCommand(test, block, null); } return block; }
private Expression GetIdentityCheck(TableExpression root, MappingEntity entity, Expression instance, MappingTable table) { if (this.mapping.IsExtensionTable(table)) { var keyColNames = this.mapping.GetExtensionKeyColumnNames(table).ToArray(); var relatedMembers = this.mapping.GetExtensionRelatedMembers(table).ToArray(); Expression where = null; for (int i = 0, n = keyColNames.Length; i < n; i++) { var relatedMember = relatedMembers[i]; var cex = new ColumnExpression(TypeHelper.GetMemberType(relatedMember), this.GetColumnType(entity, relatedMember), root.Alias, keyColNames[n]); var nex = this.GetMemberExpression(instance, entity, relatedMember); var eq = cex.Equal(nex); where = (where != null) ? where.And(eq) : where; } return where; } else { return base.GetIdentityCheck(root, entity, instance); } }
public override Expression GetUpdateExpression(MappingEntity entity, Expression instance, LambdaExpression updateCheck, LambdaExpression selector, Expression @else) { var tables = this.mapping.GetTables(entity); if (tables.Count < 2) { return base.GetUpdateExpression(entity, instance, updateCheck, selector, @else); } var commands = new List<Expression>(); foreach (var table in this.GetDependencyOrderedTables(entity)) { TableExpression tex = new TableExpression(new TableAlias(), entity, this.mapping.GetTableName(table)); var assignments = this.GetColumnAssignments(tex, instance, entity, (e, m) => this.mapping.GetAlias(e, m) == this.mapping.GetAlias(table) && this.mapping.IsUpdatable(e, m), null); var where = this.GetIdentityCheck(tex, entity, instance); commands.Add(new UpdateCommand(tex, where, assignments)); } if (selector != null) { commands.Add( new IFCommand( this.Translator.Linguist.Language.GetRowsAffectedExpression(commands[commands.Count-1]).GreaterThan(Expression.Constant(0)), this.GetUpdateResult(entity, instance, selector), @else ) ); } else if (@else != null) { commands.Add( new IFCommand( this.Translator.Linguist.Language.GetRowsAffectedExpression(commands[commands.Count-1]).LessThanOrEqual(Expression.Constant(0)), @else, null ) ); } Expression block = new BlockCommand(commands); if (updateCheck != null) { var test = this.GetEntityStateTest(entity, instance, updateCheck); return new IFCommand(test, block, null); } return block; }
private IEnumerable<ColumnAssignment> GetRelatedColumnAssignments(Expression expr, MappingEntity entity, MappingTable table, Dictionary<MemberInfo, Expression> map) { if (this.mapping.IsExtensionTable(table)) { var keyColumns = this.mapping.GetExtensionKeyColumnNames(table).ToArray(); var relatedMembers = this.mapping.GetExtensionRelatedMembers(table).ToArray(); for (int i = 0, n = keyColumns.Length; i < n; i++) { MemberInfo member = relatedMembers[i]; Expression exp = map[member]; yield return new ColumnAssignment((ColumnExpression)this.GetMemberExpression(expr, entity, member), exp); } } }
public override bool IsRelationship(MappingEntity entity, MemberInfo member) { return base.IsRelationship(entity, member) || this.IsNestedEntity(entity, member); }
private IEnumerable<ColumnAssignment> GetColumnAssignments( Expression table, Expression instance, MappingEntity entity, Func<MappingEntity, MemberInfo, bool> fnIncludeColumn, Dictionary<MemberInfo, Expression> map) { foreach (var m in this.mapping.GetMappedMembers(entity)) { if (this.mapping.IsColumn(entity, m) && fnIncludeColumn(entity, m)) { yield return new ColumnAssignment( (ColumnExpression)this.GetMemberExpression(table, entity, m), this.GetMemberAccess(instance, m, map) ); } else if (this.mapping.IsNestedEntity(entity, m)) { var assignments = this.GetColumnAssignments( table, Expression.MakeMemberAccess(instance, m), this.mapping.GetRelatedEntity(entity, m), fnIncludeColumn, map ); foreach (var ca in assignments) { yield return ca; } } } }
/// <summary> /// 获取映射实体对象的主键对象。 /// </summary> /// <param name="entity">The entity.</param> /// <param name="instance">The instance.</param> /// <returns></returns> public abstract object GetPrimaryKey(MappingEntity entity, object instance);
/// <summary> /// 通过表达式获取映射实体对象的主键对象。 /// </summary> /// <param name="entity">The entity.</param> /// <param name="source">The source.</param> /// <param name="keys">The keys.</param> /// <returns></returns> public abstract Expression GetPrimaryKeyQuery(MappingEntity entity, Expression source, Expression[] keys);
public virtual IEnumerable<MappingTable> GetDependencyOrderedTables(MappingEntity entity) { var lookup = this.mapping.GetTables(entity).ToLookup(t => this.mapping.GetAlias(t)); return this.mapping.GetTables(entity).Sort(t => this.mapping.IsExtensionTable(t) ? lookup[this.mapping.GetExtensionRelatedAlias(t)] : null); }
/// <summary> /// Clones the entity. /// </summary> /// <param name="entity">The entity.</param> /// <param name="instance">The instance.</param> /// <returns></returns> public abstract object CloneEntity(MappingEntity entity, object instance);
/// <summary> /// 获取映射实体的成员列表。 /// </summary> /// <param name="entity">The entity.</param> /// <returns></returns> public abstract IEnumerable<MemberInfo> GetMappedMembers(MappingEntity entity);
/// <summary> /// Get a query expression that selects all entities from a table /// </summary> /// <param name="entity">The entity.</param> /// <returns></returns> public abstract ProjectionExpression GetQueryExpression(MappingEntity entity);
/// <summary> /// 判断指定的映射实体成员是否是主键列。 /// </summary> /// <param name="entity"></param> /// <param name="member"></param> /// <returns></returns> public abstract bool IsPrimaryKey(MappingEntity entity, MemberInfo member);
/// <summary> /// Get an expression for a mapped property relative to a root expression. /// The root is either a TableExpression or an expression defining an entity instance. /// </summary> /// <param name="root"></param> /// <param name="entity"></param> /// <param name="member"></param> /// <returns></returns> public abstract Expression GetMemberExpression(Expression root, MappingEntity entity, MemberInfo member);
/// <summary> /// Gets the primary key members. /// </summary> /// <param name="entity">The entity.</param> /// <returns></returns> public virtual IEnumerable<MemberInfo> GetPrimaryKeyMembers(MappingEntity entity) { return this.GetMappedMembers(entity).Where(m => this.IsPrimaryKey(entity, m)); }
/// <summary> /// Get an expression that represents the insert operation for the specified instance. /// </summary> /// <param name="entity">The entity.</param> /// <param name="instance">The instance to insert.</param> /// <param name="selector">A lambda expression that computes a return value from the operation.</param> /// <param name="indeedColumns">指定需要插入的列.</param> /// <returns></returns> public abstract Expression GetInsertExpression(MappingEntity entity, Expression instance, LambdaExpression selector, ColumnIndeedExpression indeedColumns);
/// <summary> /// 判断指定映射实体的成员是否被影射为关联实体。 /// </summary> /// <param name="entity">指定映射实体</param> /// <param name="member">成员</param> /// <returns></returns> public abstract bool IsRelationship(MappingEntity entity, MemberInfo member);
/// <summary> /// Get an expression that represents the insert-or-update operation for the specified instance. /// </summary> /// <param name="entity"></param> /// <param name="instance"></param> /// <param name="updateCheck"></param> /// <param name="resultSelector"></param> /// <returns></returns> public abstract Expression GetInsertOrUpdateExpression(MappingEntity entity, Expression instance, LambdaExpression updateCheck, LambdaExpression resultSelector);
/// <summary> /// Determines if a relationship property refers to a single entity (as opposed to a collection.) /// 判断知道的映射实体的成员是否是单一实体映射关联。 /// </summary> /// <param name="entity">The entity.</param> /// <param name="member">The member.</param> /// <returns> /// <c>true</c> if [is singleton relationship] [the specified entity]; otherwise, <c>false</c>. /// </returns> public virtual bool IsSingletonRelationship(MappingEntity entity, MemberInfo member) { if (!this.IsRelationship(entity, member)) return false; Type ieType = TypeHelper.FindIEnumerable(TypeHelper.GetMemberType(member)); return ieType == null; }
/// <summary> /// Initializes a new instance of the <see cref="EntityInfo"/> struct. /// </summary> /// <param name="instance">The instance.</param> /// <param name="mapping">The mapping.</param> public EntityInfo(object instance, MappingEntity mapping) { this.instance = instance; this.mapping = mapping; }
private Dictionary<string, List<MemberInfo>> GetDependentGeneratedColumns(MappingEntity entity) { return (from xt in this.mapping.GetTables(entity).Where(t => this.mapping.IsExtensionTable(t)) group xt by this.mapping.GetExtensionRelatedAlias(xt)) .ToDictionary( g => g.Key, g => g.SelectMany(xt => this.mapping.GetExtensionRelatedMembers(xt)).Distinct().ToList() ); }