private void completeOneToManyProperty(Serializable incompleteObject, string propertyName)
        {
            Type containingTypeOfProperty = incompleteObject.getOneToManyPropertyType(propertyName);

            Serializable containingTypeOfPropertyInstance = (Serializable)Activator.CreateInstance(containingTypeOfProperty);

            string intermediateTable = incompleteObject.getOneToManyTable(propertyName);
            string currentForeignKey = incompleteObject.getOneToManyFk(propertyName);
            string currentPrimaryKey = incompleteObject.getOneToManyPk(propertyName);

            object currentIdValue = incompleteObject.getPkValue();

            string expected = "@" + currentPrimaryKey;
            List <SqlParameter> sqlParameters = new List <SqlParameter>();

            DataBase.Instance.agregarParametro(sqlParameters, expected, currentIdValue);

            string query          = "select * from " + intermediateTable + " ";
            string conditionQuery = "where " + currentPrimaryKey + "=" + expected;

            if (containingTypeOfPropertyInstance.getTableName() != intermediateTable)
            {
                query += "inner join " + containingTypeOfPropertyInstance.getTableName() +
                         " on(" + intermediateTable + "." + currentForeignKey + "=" +
                         containingTypeOfPropertyInstance.getTableName() + "." +
                         containingTypeOfPropertyInstance.
                         getMapFromKey(containingTypeOfPropertyInstance.getIdPropertyName()) + ") ";
            }

            query += conditionQuery;

            Type listType = incompleteObject.getPropertyType(propertyName);

            object dummyList = Activator.CreateInstance(listType);

            //Asigno una lista vacia a la propiedad
            incompleteObject.GetType().GetProperty(propertyName).
            SetValue(incompleteObject, dummyList);

            foreach (var item in executeQuery(query, sqlParameters, containingTypeOfProperty))
            {
                List <object> parameters = new List <object> {
                    item
                };
                incompleteObject.GetType().GetProperty(propertyName).
                PropertyType.GetMethod("Add").
                Invoke(incompleteObject.getPropertyValue(propertyName), parameters.ToArray());
            }
        }
        private void updateOneToManyProperty(Serializable objeto, string propertyName, bool cascadeMode)
        {
            object propertyList = objeto.getPropertyValue(propertyName);

            //SI es cascade updateo cada elemento de la propiedad oneToMany
            if (cascadeMode)
            {
                foreach (var item in (IEnumerable)propertyList)
                {
                    updateCascade((Serializable)item);
                }
            }

            object        notExistentFkObjects = Activator.CreateInstance(objeto.getPropertyType(propertyName));
            List <object> existentFks          = new List <object>();

            string expected = "@" + objeto.getOneToManyPk(propertyName);
            List <SqlParameter> sqlParameters = new List <SqlParameter>();

            DataBase.Instance.agregarParametro(sqlParameters, expected, objeto.getPkValue());

            string existentFksQuery = "select " + objeto.getOneToManyFk(propertyName)
                                      + " from " + objeto.getOneToManyTable(propertyName) + " where "
                                      + objeto.getOneToManyPk(propertyName) + "=" + expected;

            foreach (Dictionary <string, object> item in DataBase.Instance.ejecutarConsulta(existentFksQuery, sqlParameters))
            {
                existentFks.Add(item[objeto.getOneToManyFk(propertyName)]);
            }

            foreach (var item in (IEnumerable)propertyList)
            {
                if (!existentFks.Contains(((Serializable)item).getPropertyValue(((Serializable)item).getIdPropertyName())))
                {
                    List <object> parameters = new List <object> {
                        item
                    };
                    notExistentFkObjects.GetType().GetMethod("Add").Invoke(notExistentFkObjects, parameters.ToArray());
                }
            }

            //Seteo lista filtrada
            objeto.GetType().GetProperty(propertyName).SetValue(objeto, notExistentFkObjects);

            insertOneToManyProperty(objeto, propertyName, false);
            //Dejo todo como estaba
            objeto.GetType().GetProperty(propertyName).SetValue(objeto, propertyList);
        }
        private object unSerialize(Dictionary <string, object> dictionary, Type modelClassType)
        {
            Serializable objeto = (Serializable)Activator.CreateInstance(modelClassType);

            Dictionary <string, object> dictionaryAux = copyDictionary(dictionary);

            foreach (String dataName in dictionary.Keys)
            {
                String propertyName = objeto.getMapFromVal(dataName);
                String keyToRemove  = dataName;

                if (propertyName != "")
                {
                    Type propertyType = objeto.getPropertyType(propertyName);

                    bool isSerializable = typeof(Serializable).IsAssignableFrom(propertyType);

                    if (dictionary[dataName].ToString() != "")//Esto esta hardcodeado para que no setee cosas en null
                    {
                        if (isSerializable)
                        {
                            Serializable propertyInstance = (Serializable)Activator.CreateInstance(propertyType);
                            keyToRemove = propertyInstance.getMapFromKey(propertyInstance.getIdPropertyName());

                            object dataValue = dictionaryAux[dataName];
                            dictionaryAux.Remove(dataName);

                            if (!dictionaryAux.ContainsKey(keyToRemove))//parchado porque rompio en un test diciendo que ya se habia insertado la clave
                            {
                                dictionaryAux.Add(keyToRemove, dataValue);
                            }

                            objeto.GetType().GetProperty(propertyName).SetValue(objeto, unSerialize(dictionaryAux, propertyType));
                        }

                        else
                        {
                            object dataValue = getCastedValue(dictionary[dataName], objeto.getPropertyType(propertyName));
                            objeto.GetType().GetProperty(propertyName).SetValue(objeto, dataValue);
                        }
                        dictionaryAux.Remove(keyToRemove);
                    }
                }
            }

            return(objeto);
        }
        private Dictionary <string, object> getPropertyValues(Serializable objeto, bool nullValuesPermited)
        {
            Dictionary <string, object> dictionary = new Dictionary <string, object>();

            foreach (MemberInfo info in objeto.GetType().GetMembers())
            {
                if (info.MemberType == MemberTypes.Property)
                {
                    string propertyName = ((PropertyInfo)info).Name;

                    object propertyValue = ((PropertyInfo)info).GetValue(objeto);

                    if (propertyValue != null || nullValuesPermited)
                    {
                        dictionary.Add(propertyName, propertyValue);
                    }
                }
            }

            return(dictionary);
        }
        internal void completeProperty(Serializable incompleteObject, string propertyName, object propertyValue, bool ignoreLazyProperty)
        {
            if (incompleteObject.getFetchType(propertyName) == FetchType.EAGER || !ignoreLazyProperty)
            {
                if (incompleteObject.isOneToManyProperty(propertyName))
                {
                    completeOneToManyProperty(incompleteObject, propertyName);
                }

                if (typeof(Serializable).IsAssignableFrom(incompleteObject.getPropertyType(propertyName)) && propertyValue != null)
                {
                    Serializable serializableProperty = (Serializable)propertyValue;

                    Type propertyType = serializableProperty.GetType();

                    object propertyId = serializableProperty.getPkValue();

                    serializableProperty = (Serializable)selectById(propertyId, propertyType);

                    incompleteObject.GetType().GetProperty(propertyName).SetValue(incompleteObject, serializableProperty);
                }
            }
        }
        private void createOneToManyTable(Serializable objeto, string propertyName)
        {
            Type containingTypeOfProperty = objeto.getOneToManyPropertyType(propertyName);

            Serializable containingTypeOfPropertyInstance = (Serializable)Activator.CreateInstance(containingTypeOfProperty);

            string pkName    = objeto.getOneToManyPk(propertyName);
            string tableName = objeto.getOneToManyTable(propertyName);
            string fkName    = objeto.getOneToManyFk(propertyName);

            string pkDataTypeName = getDataTypeName(objeto.GetType().
                                                    GetProperty(objeto.getIdPropertyName()).PropertyType);

            string fkDataTypeName = getDataTypeName(containingTypeOfPropertyInstance.GetType().
                                                    GetProperty(containingTypeOfPropertyInstance.
                                                                getIdPropertyName()).PropertyType);

            string createQuery = "create table " + tableName + "(" + pkName + " " +
                                 pkDataTypeName + " ," + fkName + " " + fkDataTypeName + ", " +
                                 "primary key(" + pkName + "," + fkName + "))";

            DataBase.Instance.ejecutarConsulta(createQuery);
        }
        private void insert(Serializable objeto, String primaryKeyPropertyName, String tableName, bool cascade)
        {
            String insertQuery = "insert into " + tableName + "(";

            String valuesString = " values (";

            List <SqlParameter> parametros = new List <SqlParameter>();

            Dictionary <string, object> propertyValues = getPropertyValues(objeto);

            foreach (KeyValuePair <string, object> keyValuePair in propertyValues)
            {
                if (keyValuePair.Key != primaryKeyPropertyName || objeto.getPrimaryKeyType() == PrimaryKeyType.NATURAL)
                {
                    String dataName = objeto.getMapFromKey(keyValuePair.Key);

                    if (dataName != "")
                    {
                        insertQuery += dataName + ",";

                        valuesString += "@" + dataName + ",";

                        bool isSerializableProperty = typeof(Serializable).IsAssignableFrom(keyValuePair.Value.GetType());

                        Serializable serializableProperty = isSerializableProperty ? (Serializable)keyValuePair.Value : null;

                        if (cascade && isSerializableProperty)
                        {
                            insert(serializableProperty, serializableProperty.getIdPropertyName(), serializableProperty.getTableName(), true);
                        }

                        object parametro = isSerializableProperty ? serializableProperty.getPropertyValue(
                            serializableProperty.getIdPropertyName()) : keyValuePair.Value;

                        DataBase.Instance.agregarParametro(parametros, "@" + dataName, parametro);
                    }
                }
            }

            string primaryKeyName = objeto.getMapFromKey(objeto.getIdPropertyName());

            insertQuery  = insertQuery.Remove(insertQuery.Length - 1);
            valuesString = valuesString.Remove(valuesString.Length - 1);
            insertQuery += ") " + "output inserted." + primaryKeyName
                           + valuesString + ")";

            object insertResult = DataBase.Instance.ejecutarConsulta(
                insertQuery, parametros)[0][primaryKeyName];

            Type idType = objeto.getPropertyType(objeto.getIdPropertyName());

            object idValue = null;

            if (typeof(Serializable).IsAssignableFrom(idType))
            {
                idValue = objeto.getIdValue();
                Serializable serializableId = (Serializable)idValue;
                serializableId.GetType().GetProperty(serializableId.getIdPropertyName()).
                SetValue(serializableId,
                         getCastedValue(insertResult,
                                        serializableId.
                                        getPropertyType(serializableId.getIdPropertyName())));
            }
            else
            {
                idValue = getCastedValue(insertResult, idType);
            }

            objeto.GetType().GetProperty(objeto.getIdPropertyName()).SetValue(objeto, idValue);

            foreach (var item in objeto.getOneToManyPropertyNames())
            {
                insertOneToManyProperty(objeto, item, cascade);
            }
        }