3

I have a table

ID | ImagePath
-------------------
 1 | ~/files/1.png

My model class has

public Int64 ID { ... }
public string ImagePath { ... }

I am trying to find an approach to store the image on a file. I was thinking in creating a byte[] property and only write the file when I call SaveChanges.

Is it possible? Is there some event that fires when changes are saved that I can use only in this case?

Or is there some better approach to store path on the database and files on the disk?

Davide Piras
  • 43,984
  • 10
  • 98
  • 147
BrunoLM
  • 97,872
  • 84
  • 296
  • 452
  • Hi, I would save everything only in the database and not mixed approach db and file system. This simplifies very much portability and backup of data, just a backup/restore on another machine for example is enough without any manual copy of spare files from some folders... – Davide Piras Feb 18 '11 at 11:49
  • @Davide, not possible. This project might reach TB of images. ( http://stackoverflow.com/q/3748/340760 ) – BrunoLM Feb 18 '11 at 11:53
  • @Davide You're right ... and I'd add that storing more than ~20k of images in one folder will result performance issues on your target platform. You'll have to create a hashed folder structure for your image ID to handle this (been there, done that). – Filburt Feb 18 '11 at 11:58
  • Sergey's answer is pretty good for what you want. If you're interessted in creating and handling a hashed folder structure I'll some code. – Filburt Feb 18 '11 at 12:15

1 Answers1

1

In one of my projects i store files just in folder and FilePath in database for linked entity(relation is 1-to-1). I just created entity for File with byte[] property and domain service for saving files on server. In InsertFile i call filehandler that saves bytes on disk.

public IQueryable<WebFile> GetFiles()
        {

            string path = "~/Upload";

            List<WebFile> webFiles = new List<WebFile>();

            if (string.IsNullOrEmpty(path)) return webFiles.AsQueryable();

            DirectoryInfo di = new DirectoryInfo(HttpContext.Current.Server.MapPath(path));

            foreach (FileInfo file in di.GetFiles())
            {

                webFiles.Add(new WebFile { FileName = file.Name });

            }

            return webFiles.AsQueryable();

        }

        public void InsertFile(WebFile file)
        {

            FileHandler.HandleFile(file);

        }

Link in database is just filename (because there is one folder, no reason to storing full path)

FileHandler code:

public class FileHandler
    {
        public static void HandleFile(WebFile file)
        {

            string uploadDir = "~/Upload";

            if (!string.IsNullOrEmpty(uploadDir))
            {

                if (uploadDir.IndexOf("~/") == 0)

                    uploadDir = HttpContext.Current.Server.MapPath(uploadDir);

                if (uploadDir.LastIndexOf("/") == uploadDir.Length - 1)

                    uploadDir = uploadDir.Substring(0, uploadDir.Length - 1);

                string fullFileName = string.Format("{0}/{1}", uploadDir, file.FileName);

                if (File.Exists(fullFileName))
                {

                    string ext = fullFileName.Substring(fullFileName.LastIndexOf("."));

                    string fName = fullFileName.Substring(0, fullFileName.LastIndexOf("."));

                    fullFileName = string.Format("{0}_1{1}", fName, ext);

                }

                File.WriteAllBytes(fullFileName, file.FileContent);

            }

        }
    }
Sergey Vedernikov
  • 7,609
  • 2
  • 25
  • 27