예제 #1
0
        /// <summary>
        /// Saves an entity to the default path.
        /// </summary>
        /// <param name="entity">The entity identifier.</param>
        /// <param name="overwrite">If true, force overwrite, default is false.</param>
        public void SaveEntity(EntityWithKey entity, bool useLock = false, bool overwrite = false)
        {
            List <EntityWithKey> entities = new List <EntityWithKey>();

            entities.Add(entity);

            entityManager.SaveEntities(entities, defaultStoragePath, Path.Combine(defaultStoragePath, structFileName), useLock, overwrite);
        }
예제 #2
0
        /// <summary>
        /// Loads an entity from the given path.
        /// </summary>
        /// <param name="entity">The entity identifier.</param>
        /// <param name="path">The path.</param>
        public void LoadEntity(EntityWithKey entity, string path, bool useLock = false)
        {
            List <EntityWithKey> entities = new List <EntityWithKey>();

            entities.Add(entity);

            entityManager.LoadEntities(entities, path, Path.Combine(path, structFileName), useLock);
        }
예제 #3
0
        /// <summary>
        /// Composes a single entity into raw data that it adds to the given result list starting from <paramref name="rowIndex"/>.
        /// That resulting raw data may potentially span multiple rows if the entity has a weak collection associated with it.
        /// This function is the opposite of <see cref="DataParser.ParseRow"/>.
        /// </summary>
        /// <param name="result">The result list containing the raw data.</param>
        /// <param name="entity">The <see cref="EntityWithKey"/> to translate into raw data</param>
        /// <param name="mapping">The <see cref="MappingInfo"/> to rely on when mapping the entity to raw data.</param>
        /// <param name="rowIndex">The row index at which to start adding the raw data.</param>
        /// <param name="columnCount">The total number of columns in the result, calculated once and passed to the recursive function for efficiency.</param>
        /// <returns>The number of rows occupied by the composed result.</returns>
        private int ComposeDataRowsFromEntity(EntityWithKey baseEntity, MappingInfo mapping, List <string[]> result, int rowIndex, int columnCount)
        {
            // Get the row, or create it if missing
            string[] dataRow = null;
            while (rowIndex >= result.Count)
            {
                result.Add(dataRow = new string[columnCount]);
            }

            dataRow ??= result[rowIndex];

            // Hydrate the simple props
            foreach (var simpleProp in mapping.SimpleProperties)
            {
                var entity = simpleProp.GetTerminalEntityForRead(baseEntity);
                if (!entity.EntityMetadata.IsLoaded(simpleProp.Metadata.Descriptor.Name))
                {
                    throw new InvalidOperationException($"Bug: Attempt to export unloaded property {simpleProp.Metadata.Descriptor.Name} from type {entity.GetType().Name}.");
                }

                if (simpleProp is ForeignKeyMappingInfo fkProp && fkProp.NotUsingIdAsKey)
                {
                    var navPropertyDesc = fkProp.NavPropertyMetadata.Descriptor;
                    if (!entity.EntityMetadata.IsLoaded(navPropertyDesc.Name))
                    {
                        throw new InvalidOperationException($"Bug: Attempt to export unloaded property {navPropertyDesc.Name} from type {entity.GetType().Name}.");
                    }

                    object navObj = navPropertyDesc.GetValue(entity);
                    if (navObj != null)
                    {
                        if (navObj is EntityWithKey navEntity)
                        {
                            var keyPropertyDesc = fkProp.KeyPropertyMetadata.Descriptor;
                            if (!navEntity.EntityMetadata.IsLoaded(keyPropertyDesc.Name))
                            {
                                throw new InvalidOperationException($"Bug: Attempt to export unloaded property {keyPropertyDesc.Name} from type {navEntity.GetType().Name}.");
                            }

                            var keyValue       = keyPropertyDesc.GetValue(navEntity);
                            var keyStringValue = fkProp.KeyPropertyMetadata.Format(keyValue);
                            if (string.IsNullOrWhiteSpace(keyStringValue))
                            {
                                // var stringId = navEntity.GetId()?.ToString() ?? throw new InvalidOperationException($"Bug: Entity with key of type {navEntity.GetType().Name} was loaded without its Id");
                                keyStringValue = $"(undefined)"; // Ensures that if entity is not null, the key value is also not null, otherwise the import might be different
                            }
                            dataRow[fkProp.Index] = keyStringValue;
                        }
                        else
                        {
                            throw new InvalidOperationException($"Bug: Navigation Property {navPropertyDesc.Name} from type {entity.GetType().Name} returned a non-{nameof(EntityWithKey)}.");
                        }
                    }
                }
예제 #4
0
        public static void AddEntity(this RelatedEntities relatedEntities, EntityWithKey entity)
        {
            if (entity == null)
            {
                return;
            }

            var type       = entity.GetType();
            var desc       = TypeDescriptor.Get(type);
            var collection = type.Name;

            var list = relatedEntities.GetList(collection);

            if (list == null)
            {
                list = desc.CreateList();
                relatedEntities.SetList(collection, list);
            }

            list.Add(entity);
        }