2011-02-18 8 views
3

J'ai une tableComment stocker des images sur disque et un lien vers la base de données avec EF?

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

Ma classe modèle a

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

Je suis en train de trouver une approche pour stocker l'image sur un fichier. Je pensais en créant une propriété byte[] et écris seulement le dossier quand j'appelle SaveChanges.

Est-ce possible? Y at-il un événement qui se déclenche lorsque des modifications sont enregistrées que je ne peux utiliser que dans ce cas?

Ou est-il une meilleure approche pour stocker path sur la base de données et files sur le disque?

+0

Salut, je sauverais tout seul dans la base de données et pas mixte approche DB et système de fichiers. Cela simplifie énormément la portabilité et la sauvegarde des données, juste une sauvegarde/restauration sur une autre machine par exemple suffit sans aucune copie manuelle des fichiers de sauvegarde de certains dossiers ... –

+0

@Davide, pas possible. Ce projet pourrait atteindre le TB d'images. (http://stackoverflow.com/q/3748/340760) – BrunoLM

+0

@Davide Vous avez raison ... et j'ajouterais que stocker plus de ~ 20k d'images dans un dossier entraînera des problèmes de performances sur votre plate-forme cible. Vous devrez créer une structure de dossier haché pour votre ID d'image pour gérer cela (été là, fait cela). – Filburt

Répondre

1

Dans l'un de mes projets, je stocke les fichiers uniquement dans le dossier et FilePath dans la base de données pour l'entité liée (la relation est 1-à-1). Je viens de créer l'entité pour le fichier avec la propriété byte [] et le service de domaine pour l'enregistrement des fichiers sur le serveur. Dans InsertFile, j'appelle filehandler qui sauvegarde les octets sur le disque.

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 dans la base de données est tout simplement le nom de fichier (car il y a un dossier, aucune raison de stocker le chemin complet)

code FileHandler:

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); 

      } 

     } 
    } 
+0

Est-ce que 'if (uploadDir.EndsWith ("/"))' ne serait pas plus simple? – Filburt

+0

peut être, ce code a été codé rapidement et peut contenir quelques défauts :) mais l'idée est visible –

+0

Toujours envie de sucre syntactical ;-) – Filburt

Questions connexes