/// <summary>
        /// Gets the file associated with a custom material property - or null if the file could not be found.
        /// </summary>
        /// <param name="id">The ID of the material to get a file for.</param>
        /// <param name="prop">The custom prop to get the file from.</param>
        /// <returns>Returns the file path or null</returns>
        public string GetCustomPropFilePath(int id, CustomMaterialProp prop)
        {
            // Make sure the material exists
            Material material = GetMaterialOrThrowNotFoundException(id);

            // Get and validate target directory
            string basePath = Path.Combine(Confguration.GetValue <string>("Files:Path"), id.ToString());

            if (!Directory.Exists(basePath))
            {
                Directory.CreateDirectory(basePath);
                return(null);
            }

            // Get file path
            CustomMaterialPropValue propValue = material.CustomProps.FirstOrDefault(p => p.PropId == prop.Id);
            string filePath = (string)propValue.Value;

            // Validate file and return path (or null)
            if (File.Exists(filePath))
            {
                return(filePath);
            }
            else
            {
                return(null);
            }
        }
        public void RemoveCustomFileMaterialProp(int materialId, Guid propId)
        {
            CustomMaterialPropValue propValue = GetPropValue(materialId, propId);

            if (propValue != null)
            {
                PropValues.Remove(propValue);
            }
        }
        public void SetCustomFileMaterialProp(int materialId, Guid propId, string filePath)
        {
            CustomMaterialPropValue propValue = GetPropValue(materialId, propId);

            if (propValue == null)
            {
                PropValues.Add(new CustomMaterialPropValue()
                {
                    MaterialId = materialId,
                    PropId     = propId,
                    Value      = filePath
                });
            }
            else
            {
                propValue.Value = filePath;
            }
        }
        public void SetCustomTextMaterialProp(int materialId, Guid propId, string text)
        {
            CustomMaterialPropValue propValue = GetPropValue(materialId, propId);

            if (propValue == null)
            {
                PropValues.Add(new CustomMaterialPropValue()
                {
                    MaterialId = materialId,
                    PropId     = propId,
                    Value      = text
                });
            }
            else
            {
                propValue.Value = text;
            }
        }
        /// <summary>
        /// Sets or removes a custom material prop value of the file type.
        /// This stores the file in the file system and persists the file path as a custom material prop value.
        /// </summary>
        /// <param name="id">The material ID.</param>
        /// <param name="prop">The custom prop ID.</param>
        /// <param name="file">The file to set, or null.</param>
        public void UpdateCustomFileMaterialProp(int id, CustomMaterialProp prop, IFormFile file)
        {
            // Make sure the material exists
            Material material = GetMaterialOrThrowNotFoundException(id);

            // Get and validate target directory
            string basePath = Path.Combine(Confguration.GetValue <string>("Files:Path"), id.ToString());

            if (!Directory.Exists(basePath))
            {
                Directory.CreateDirectory(basePath);
            }

            if (file == null)
            {
                // Get file path
                CustomMaterialPropValue propValue = material.CustomProps.FirstOrDefault(p => p.PropId == prop.Id);
                string filePath = (string)propValue.Value;

                // Delete file
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                }
                CustomMaterialPropValueRepository.RemoveCustomFileMaterialProp(id, prop.Id);
            }
            else
            {
                // Write file
                string filePath = Path.Combine(basePath, file.FileName);
                using (FileStream stream = File.Create(filePath))
                {
                    file.CopyTo(stream);
                }
                CustomMaterialPropValueRepository.SetCustomFileMaterialProp(id, prop.Id, filePath);
            }
        }