コード例 #1
0
ファイル: ORMEntity.cs プロジェクト: RickvdLaan/ORM
        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());
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
ファイル: ORMEntity.cs プロジェクト: RickvdLaan/ORM
        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);
        }
コード例 #4
0
ファイル: SQLHelper.cs プロジェクト: RickvdLaan/ORM
        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");
                    }
                }
            }
        }