Jak przechowywać obrazy przy użyciu Entity Framework Code First CTP 5?

83

Po prostu próbuję dowiedzieć się, czy istnieje prosty sposób przechowywania i pobierania danych binarnych (plików) przy użyciu EF Code First CTP 5? Naprawdę chciałbym, żeby używał typu FILESTREAM, ale naprawdę szukam sposobu, aby to zadziałało.

Max Schmeling
źródło

Odpowiedzi:

41

W FILESTREAMEF nie można używać języka SQL . EF ma działać na różnych serwerach baz danych, ale funkcja strumienia plików jest specyficzną cechą SQL 2008 i nowszych. Możesz spróbować zrobić to starym sposobem - użyj varbinary(max)w swojej tabeli bazy danych i użyj tablicy bajtów w swojej zmapowanej klasie.

Edytować:

Małe wyjaśnienie - możesz użyć FILESTREAMw bazie danych, ale EF nie będzie korzystał z przesyłania strumieniowego. Wczyta go standardowo varbinary(max).

Ladislav Mrnka
źródło
113

Zawsze tworzę inną klasę, taką jak ProductImagew przypadku asocjacji jeden do jednego, aby zarządzać leniwym ładowaniem, a także normalizować tabelę:

public class ProductImage
{
    public int ProductId { get; private set; }
    public byte[] Image { get; set; }
}
nima
źródło
4
Czy nie byłoby znacznie prościej utworzyć widok, który nie zawiera kolumny obrazu pliku, a następnie utworzyć drugą jednostkę w EF, która wskazuje widok zamiast tabeli - powiedzmy, np. „ProductLite”
C.List
@ C.List Nie mogę uwierzyć, że używam EF od lat i nigdy o tym nie myślałem. To wspaniały pomysł i po prostu go wykorzystałem, pozbywając się niepotrzebnego poglądu, którego używałem do zrobienia tego samego. Nazwijmy to „wirtualną istotą” :)
Greg Gum
65

Po prostu zadeklaruj swoją własność jako bajt [], jak wspomniał Ladislav.

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

    public string Name { get; set; }

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

To wszystko. Jeśli nie zmapujesz właściwości, konwencja jest mapowana na varbinary(max). Jeśli masz już kolumnę obrazu w bazie danych, po prostu dodaj [Column(TypeName = "image")]właściwość ProductImage lub jeśli wolisz mapowanie kodu, dodaj to do przesłonięcia OnModelCreating w klasie kontekstu:

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

Problem polega na tym, że nie znalazłem sposobu na rozleniwienie właściwości, ponieważ niekoniecznie chcę ładować dane binarne za każdym razem, gdy pobieram produkt. Nie jestem pewien, czy dobrze pamiętam, ale NHibernate może to zrobić po wyjęciu z pudełka.

Cosmin Onea
źródło
Tak, NHibernate może wykonać leniwe ładowanie specyficzne dla kolumny po wyjęciu z pudełka: ayende.com/blog/4377/nhibernate-new-feature-lazy-properties .
gabe