Как хранить изображения с помощью Entity Framework Code First CTP 5?

83

Я просто пытаюсь выяснить, есть ли простой способ хранить и извлекать двоичные (файловые) данные с помощью EF Code First CTP 5? Мне бы очень хотелось, чтобы он использовал тип FILESTREAM, но на самом деле я просто ищу способ заставить его работать.

Макс Шмелинг
источник

Ответы:

41

Вы не можете использовать SQL FILESTREAMв EF. Предполагается, что EF работает поверх разных серверов баз данных, но функция потока файлов - это особенность SQL 2008 и новее. Вы можете попробовать сделать это по-старому - использовать varbinary(max)в таблице базы данных и использовать массив байтов в сопоставленном классе.

Редактировать:

Небольшое уточнение - вы можете использовать FILESTREAMв базе данных, но EF не будет использовать потоковую передачу. Он загрузит его стандартно varbinary(max).

Ладислав Мрнка
источник
113

Я всегда создаю другой класс, например, ProductImageс однозначной связью, чтобы управлять отложенной загрузкой, а также нормализовать таблицу:

public class ProductImage
{
    public int ProductId { get; private set; }
    public byte[] Image { get; set; }
}
нима
источник
4
Не было бы намного проще создать представление, которое не включает столбец изображения файла, а затем создать второй объект в EF, который указывает на представление вместо таблицы - скажем, например, «ProductLite»
C.List
@ C.List Не могу поверить, что использую EF в течение многих лет и никогда не думал об этом. Это потрясающая идея, и я просто использовал ее, избавившись от ненужного представления, которое я использовал, чтобы сделать то же самое. Назовем это «виртуальная сущность» :)
Грег Гам
65

Просто объявите свою собственность как byte [], как упомянул Ладислав.

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

    public string Name { get; set; }

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

Это почти все. Если вы не сопоставляете свойство, по соглашению оно отображается на varbinary(max). Если у вас есть столбец изображения в базе данных, просто добавьте [Column(TypeName = "image")]свойство ProductImage или если вы предпочитаете сопоставление кода, добавьте это в свое переопределение OnModelCreating в классе контекста:

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

Проблема, с которой я столкнулся, заключается в том, что я не нашел способа сделать свойство ленивым, поскольку мне не обязательно загружать двоичные данные каждый раз, когда я получаю продукт. Я не уверен, что правильно помню, но NHibernate может сделать это из коробки.

Космин Онея
источник
Да, NHibernate может выполнять отложенную загрузку для конкретных столбцов из коробки: ayende.com/blog/4377/nhibernate-new-feature-lazy-properties .
gabe