/// <summary> /// Builds the specified entity. /// </summary> /// <param name="entity">The entity.</param> /// <param name="entityType">Type of the entity.</param> /// <param name="entityMap">The entity map.</param> /// <param name="executionList">The execution list.</param> /// <param name="session">The session.</param> /// <exception cref="System.ArgumentNullException">entity</exception> /// <exception cref="GoliathDataException">Property + prop.Name + not found in entity.</exception> public void Build(object entity, Type entityType, EntityMap entityMap, InsertSqlExecutionList executionList, ISession session) { if (entity == null) { throw new ArgumentNullException("entity"); } if (session == null) { throw new ArgumentNullException("session"); } if (entityMap == null) { throw new ArgumentNullException("entityMap"); } var info = new InsertSqlInfo { TableName = entityMap.TableName }; var entityAccessor = entityAccessorStore.GetEntityAccessor(entityType, entityMap); var converterStore = session.SessionFactory.DbSettings.ConverterStore; Tuple <string, PropertyAccessor, DbType?> pkTuple = null; if (entityMap.PrimaryKey != null) { pkTuple = ProcessPrimaryKey(entity, entityType, entityMap, info, entityAccessor, executionList, session); } foreach (var prop in entityMap) { if (prop.IsPrimaryKey || prop.IsAutoGenerated) { continue; } var rel = prop as Relation; if (rel != null) { ProcessRelation(rel, entity, entityMap, info, entityAccessor, executionList, converterStore, session); } else { var paramName = ParameterNameBuilderHelper.QueryParamName(entityMap, prop.ColumnName); if (!info.Columns.ContainsKey(paramName)) { PropertyAccessor pinf; if (!entityAccessor.Properties.TryGetValue(prop.Name, out pinf)) { throw new GoliathDataException("Property " + prop.Name + " not found in entity."); } info.Columns.Add(paramName, prop.ColumnName); var propVal = pinf.GetMethod(entity); //info.Parameters.Add(paramName, new QueryParam(paramName, propVal)); info.Parameters.Add(paramName, QueryParam.CreateParameter(prop, paramName, propVal)); } } } if ((pkTuple != null) && (pkTuple.Item2 != null)) { var resultType = pkTuple.Item2.PropertyType; if (!info.DelayExecute) { var pkValue = executionList.ExcuteStatement(session, info, resultType); QueryParam pkQueryParam; if (!info.Parameters.TryGetValue(pkTuple.Item1, out pkQueryParam)) { pkQueryParam = new QueryParam(pkTuple.Item1, pkTuple.Item3); } pkQueryParam.Value = pkValue; pkTuple.Item2.SetMethod(entity, pkValue); executionList.GeneratedKeys.Add(pkTuple.Item1, pkQueryParam); } else { executionList.ExcuteStatement(session, info, typeof(object)); } } else { executionList.ExcuteStatement(session, info, typeof(object)); } //check many to many relations and process them. foreach (var rel in entityMap.Relations) { if (rel.RelationType == RelationshipType.ManyToMany) { ProcessManyToManyRelation(rel, entity, entityMap, info, entityAccessor, executionList, converterStore, session); } } }
void ProcessManyToManyRelation(Relation rel, object entity, EntityMap entityMap, InsertSqlInfo info, EntityAccessor entityAccessor, InsertSqlExecutionList executionList, ITypeConverterStore converterStore, ISession session) { if ((rel.RelationType != RelationshipType.ManyToMany) || !rel.Inverse) { return; } PropertyAccessor pinf; if (!entityAccessor.Properties.TryGetValue(rel.Name, out pinf)) { throw new GoliathDataException("Property " + rel.Name + " not found in entity."); } var collection = pinf.GetMethod(entity) as System.Collections.IEnumerable; int counter = 1; if (collection != null) { foreach (var relObj in collection) { if (relObj == null) { continue; } var relEntityType = relObj.GetType(); var relEntityMap = session.SessionFactory.DbSettings.Map.GetEntityMap(relEntityType.FullName); var relEntAccessor = entityAccessorStore.GetEntityAccessor(relEntityType, relEntityMap); var paramName = ParameterNameBuilderHelper.QueryParamName(entityMap, rel.MapColumn + counter); var mapParamName = ParameterNameBuilderHelper.QueryParamName(entityMap, rel.MapReferenceColumn + counter); PropertyAccessor relPinf; if (!relEntAccessor.Properties.TryGetValue(rel.ReferenceProperty, out relPinf)) { throw new GoliathDataException("Reference " + rel.ReferenceProperty + " not found in entity."); } if (relEntityMap.PrimaryKey != null) { foreach (var pk in relEntityMap.PrimaryKey.Keys) { object pkValue; if (HasUnsavedValue(pk, relPinf, relObj, converterStore, out pkValue)) { Build(relObj, relEntityType, relEntityMap, executionList, session); } var manyToManyInfo = new InsertSqlInfo { DelayExecute = true, TableName = rel.MapTableName }; var param1 = new QueryParam(mapParamName, pk.Key.DbType) { Value = relPinf.GetMethod(relObj) }; manyToManyInfo.Columns.Add(mapParamName, rel.MapReferenceColumn); manyToManyInfo.Parameters.Add(mapParamName, param1); PropertyAccessor mappedPinf; if (!entityAccessor.Properties.TryGetValue(rel.MapPropertyName, out mappedPinf)) { throw new GoliathDataException("Property " + rel.MapPropertyName + " not found in entity" + entityMap.FullName + "."); } var param2 = new QueryParam(paramName, rel.DbType) { Value = mappedPinf.GetMethod(entity) }; manyToManyInfo.Columns.Add(paramName, rel.MapColumn); manyToManyInfo.Parameters.Add(paramName, param2); executionList.ExcuteStatement(session, manyToManyInfo, typeof(object)); } } counter++; } } }