private void InitializePrimaryKeys() { var attributes = new List <ORMPrimaryKeyAttribute>(); foreach (var property in GetType().GetProperties()) { foreach (ORMPrimaryKeyAttribute attribute in property.GetCustomAttributes(typeof(ORMPrimaryKeyAttribute), true)) { attribute.PropertyName = property.Name; attribute.ColumnName = (property.GetCustomAttributes(typeof(ORMColumnAttribute), true).FirstOrDefault() as ORMColumnAttribute)?.ColumnName ?? property.Name; attributes.Add(attribute); } } PrimaryKey = new ORMPrimaryKey(attributes.Count); if (attributes.Count > 0) { foreach (var attribute in attributes) { PrimaryKey.Add(attribute.PropertyName, attribute.ColumnName, null, attribute.IsAutoIncrement); } } else { throw new ORMPrimaryKeyAttributeNotImplementedException(GetType()); } }
public IDataReader FetchEntityByCombinedId(string tableName, ORMPrimaryKey primaryKey, List <object> ids) { if (string.IsNullOrEmpty(tableName)) { throw new ArgumentNullException(); } if (primaryKey == null) { throw new ArgumentNullException(); } if (primaryKey.Keys.Count <= 1) { throw new ArgumentException(); } if (ids == null) { throw new ArgumentNullException(); } if (ids.Count() != primaryKey.Keys.Count) { throw new ArgumentNullException(); } var path = BasePath + tableName.ToUpperInvariant(); var tableRecords = ORMUtilities.MemoryEntityDatabase.MemoryTables.DocumentElement.SelectNodes(path); foreach (XmlElement record in tableRecords) { var attributes = new List <XmlAttribute>(primaryKey.Keys.Count); foreach (var key in primaryKey.Keys) { attributes.Add(record.GetAttributeNode(key.ColumnName)); } for (int i = 0; i < attributes.Count; i++) { if (attributes[i] != null && attributes[i].Value.Equals(ids[i].ToString(), StringComparison.InvariantCultureIgnoreCase)) { if (i == attributes.Count - 1) { return(ParseDataTableFromXmlRecord(record)); } continue; } break; } } return(null); }
private ORMEntity FetchEntity(ORMPrimaryKey primaryKey, Expression joinExpression = null) { BinaryExpression whereExpression = null; for (int i = 0; i < PrimaryKey.Count; i++) { if (primaryKey.Keys[i].Value == DBNull.Value) { // DBNull, so there's nothing to fetch. return(null); } // Contains the id represented as a MemberExpression: {x.InternalPrimaryKeyName}. var memberExpression = Expression.Property(Expression.Parameter(GetType(), $"x"), GetPrimaryKeyPropertyInfo()[i]); // Contains the actual id represented as a ConstantExpression: {id_value}. var constantExpression = Expression.Constant(primaryKey.Keys[i].Value, primaryKey.Keys[i].Value.GetType()); // Combines the expressions represtend as a Expression: {(x.InternalPrimaryKeyName == id_value)} if (whereExpression == null) { whereExpression = Expression.Equal(memberExpression, constantExpression); } else { whereExpression = Expression.AndAlso(whereExpression, Expression.Equal(memberExpression, constantExpression)); } } // Instantiates and fetches the run-time collection. var collection = Activator.CreateInstance(ORMUtilities.CollectionEntityRelations[GetType()]); // Sets the InternalWhere with the WhereExpression. collection.GetType().GetMethod(nameof(ORMCollection <ORMEntity> .InternalWhere), NonPublicFlags, null, new Type[] { typeof(BinaryExpression) }, null).Invoke(collection, new object[] { whereExpression }); // Fetches the data. collection.GetType().GetMethod(nameof(ORMCollection <ORMEntity> .Fetch), NonPublicFlags, null, new Type[] { typeof(ORMEntity), typeof(long), typeof(Expression) }, null).Invoke(collection, new object[] { this, joinExpression == null ? 1 : -1, joinExpression }); if (!UnitTestUtilities.IsUnitTesting && IsNew) { return(null); } ExecutedQuery = (string)collection.GetType().GetProperty(nameof(ORMCollection <ORMEntity> .ExecutedQuery)).GetValue(collection); if (OriginalFetchedValue != null) { OriginalFetchedValue.ExecutedQuery = ExecutedQuery; } return(this); }
private static void PopulateManyToManyEntity(ORMEntity entity, IDataReader reader, SQLBuilder sqlBuilder) { Dictionary <ORMPrimaryKey, Dictionary <string, List <ORMEntity> > > manyToManyData = new Dictionary <ORMPrimaryKey, Dictionary <string, List <ORMEntity> > >(new ORMPrimaryKey()); var manyToManyJoinIndexes = new List <(string, int[])>(); var manyToManyJoinTypes = new Dictionary <string, Type>(); var tableIndex = 0; foreach (var(name, _) in sqlBuilder.TableOrder) { var objectPath = sqlBuilder.TableNameResolvePaths.ContainsKey(name) ? sqlBuilder.TableNameResolvePaths[name] : string.Empty; var tableColumnCount = sqlBuilder.TableNameColumnCount[name]; if (objectPath.StartsWith(SQLBuilder.MANY_TO_MANY_JOIN_DATA, StringComparison.Ordinal)) { var indexes = new List <int>(); for (int i = 0; i < tableColumnCount; i++) { indexes.Add(tableIndex + i); } manyToManyJoinIndexes.Add((objectPath.Split('.')[1], indexes.ToArray())); } tableIndex += tableColumnCount; } void AddManyToManyObject(ORMPrimaryKey key, IDataReader reader) { Dictionary <string, List <ORMEntity> > relations; if (manyToManyData.ContainsKey(key)) { relations = manyToManyData[key]; } else { relations = new Dictionary <string, List <ORMEntity> >(); manyToManyData[key] = relations; } foreach (var(fieldName, indexes) in manyToManyJoinIndexes) { bool IsRowEmpty(List <(string, int[])> manyToManyJoinIndexes, IDataReader reader) { foreach (var(fieldName, indexes) in manyToManyJoinIndexes) { for (int i = 0; i < indexes.Length; i++) { if (reader.GetValue(indexes[i]) == DBNull.Value) { if ((i + 1) == indexes.Length) { return(true); } } else { return(false); } } } return(true); } if (!IsRowEmpty(manyToManyJoinIndexes, reader)) { var instance = (ORMEntity)Activator.CreateInstance(manyToManyJoinTypes[fieldName]); foreach (var index in indexes) { SetEntityProperty(instance, reader, sqlBuilder, index, true); } if (relations.ContainsKey(fieldName)) { relations[fieldName].Add(instance); } else { relations[fieldName] = new List <ORMEntity>() { instance }; } } } } int[] primaryKeyIndexes = ORMPrimaryKey.DeterminePrimaryKeyIndexes(reader, entity); foreach (var(fieldName, _) in manyToManyJoinIndexes) { var type = entity.GetPropertyInfo(fieldName).PropertyType; if (!typeof(ORMEntity).IsAssignableFrom(type.GetType())) { type = ORMUtilities.CollectionEntityRelations[type]; } manyToManyJoinTypes.Add(fieldName, type); } ORMPrimaryKey pk = new ORMPrimaryKey(reader, primaryKeyIndexes); //PopulateEntity(entity, reader, sqlBuilder); AddManyToManyObject(pk, reader); foreach (var kvPair in manyToManyData) { foreach (var data in kvPair.Value) { var property = entity.GetType().GetProperty(data.Key, entity.PublicFlags); if (typeof(IORMCollection <ORMEntity>).IsAssignableFrom(property.PropertyType)) { var propertyValue = entity.GetType().GetProperty(data.Key, entity.PublicFlags).GetValue(entity); if (propertyValue == null) { var subcollection = Activator.CreateInstance(property.PropertyType); var collectionProperty = property.PropertyType.GetProperty(nameof(ORMCollection <ORMEntity> .MutableEntityCollection), entity.NonPublicFlags); var list = collectionProperty.GetValue(subcollection) as IList; foreach (var item in data.Value) { list.Add(item); } property.SetValue(entity, subcollection); } else { foreach (var item in data.Value) { propertyValue.GetType().GetMethod("Add", entity.PublicFlags).Invoke(propertyValue, new object[] { item }); } } } else { throw new Exception("Something went wrong trying to cast to a subcollection"); } } } }