Comment stocker des images en utilisant Entity Framework Code First CTP 5?

83

J'essaie juste de savoir s'il existe un moyen simple de stocker et de récupérer des données binaires (fichier) à l'aide d'EF Code First CTP 5? J'aimerais vraiment qu'il utilise le type FILESTREAM, mais je cherche vraiment un moyen de le faire fonctionner.

Max Schmeling
la source

Réponses:

41

Vous ne pouvez pas utiliser SQL FILESTREAMdans EF. EF est censé fonctionner sur différents serveurs de base de données, mais la fonction filestream est une caractéristique spécifique de SQL 2008 et plus récent. Vous pouvez essayer de le faire à l'ancienne - utilisezvarbinary(max) dans votre table de base de données et utilisez un tableau d'octets dans votre classe mappée.

Éditer:

Petite clarification - vous pouvez utiliser FILESTREAMdans la base de données mais EF ne profitera pas du streaming. Il le chargera en standard varbinary(max).

Ladislav Mrnka
la source
112

Je crée toujours une autre classe comme ProductImageavec une association one-to-one afin de gérer le chargement paresseux et aussi de normaliser la table:

public class ProductImage
{
    public int ProductId { get; private set; }
    public byte[] Image { get; set; }
}
nima
la source
4
Ne serait-il pas beaucoup plus simple de créer une vue qui n'inclut pas la colonne d'image de fichier, puis de créer une deuxième entité dans EF qui pointe vers la vue au lieu de la table - par exemple, "ProductLite"
C.List
@ C.List Je ne peux pas croire que j'utilise EF depuis des années et que je n'ai jamais pensé à le faire. C'est une idée fabuleuse et je l'ai juste mise à profit, en me débarrassant d'une vue inutile que j'utilisais pour faire la même chose. Appelons cela une "entité virtuelle" :)
Greg Gum
65

Déclarez simplement votre propriété en octet [] comme Ladislav l'a mentionné.

public class Product
{
    public int Id { get; private set; }

    public string Name { get; set; }

    public byte[] ProductImage { get; set; }
}

C'est à peu près tout. Si vous ne mappez pas la propriété, la convention est qu'elle correspond à un varbinary(max). Si vous avez déjà une colonne d'image dans la base de données, ajoutez simplement [Column(TypeName = "image")]la propriété ProductImage ou si vous préférez le mappage de code, ajoutez ceci à votre remplacement OnModelCreating dans la classe de contexte:

modelBuilder.Entity<Product>().Property(p => p.ProductImage).HasColumnType("image");

Le problème que j'ai avec cela est que je n'ai pas trouvé de moyen de rendre la propriété paresseuse car je ne veux pas nécessairement charger des données binaires chaque fois que je récupère un produit. Je ne suis pas sûr de me souvenir correctement, mais NHibernate peut le faire hors de la boîte.

Cosmin Onea
la source
Oui, NHibernate peut effectuer le chargement différé spécifique à la colonne dès sa sortie de la boîte: ayende.com/blog/4377/nhibernate-new-feature-lazy-properties .
gabe