Ядро EF — не включая двоичные поля

#entity-framework #ef-core-2.0

#entity-framework #ef-core-2.0

Вопрос:

У меня есть модель ядра EF, в которой есть двоичное поле

 class SomeModel {
    string Id;
    string otherProperty;
    byte[] blob;
};
  

Обычно, когда я запрашиваю базу данных, я хочу вернуть список этой модели — а затем, при последующих вызовах, запрашивать только один объект, но возвращать большой двоичный объект.

Я не вижу способа ни в data, ни в code first предотвратить то, чтобы ядро EF всегда оплачивало стоимость извлечения поля blob.

Я действительно хочу иметь возможность сказать что-то вроде:

 var list = await Context.SomeModels.ToListAsync();

// later
var item = await Context.SomeModels
  .Where(m=>m.Id==someId)
  .Include(m=>m.blob)
  .FirstOrDefaultAsync();
  

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

Ответ №1:

Единственный способ получить отдельную загрузку — это переместить данные в отдельный объект с отношением «один к одному».

Однако это не обязательно должна быть отдельная таблица. Хотя наиболее естественным выбором выглядит принадлежащая сущность, поскольку принадлежащие сущности всегда загружаются с владельцами, это должна быть обычная сущность, но настроенная с разделением таблицы — проще говоря, совместно использовать одну и ту же таблицу с основной сущностью.

Применяя его к вашему образцу:

Модель:

 public class SomeModel
{
    public string Id { get; set; }
    public string OtherProperty { get; set; }
    public SomeModelBlob Blob { get; set; }
};

public class SomeModelBlob
{
    public string Id { get; set; }
    public byte[] Data { get; set; }
}
  

Конфигурация:

 modelBuilder.Entity<SomeModelBlob>(builder =>
{
    builder.HasOne<SomeModel>().WithOne(e => e.Blob)
        .HasForeignKey<SomeModelBlob>(e => e.Id);
    builder.Property(e => e.Data).HasColumnName("Blob");
    builder.ToTable(modelBuilder.Entity<SomeModel>().Metadata.Relational().TableName);
});
  

Использование:

Код:

 var test = context.Set<SomeModel>().ToList();
  

SQL:

   SELECT [s].[Id], [s].[OtherProperty]
  FROM [SomeModel] AS [s]
  

Код:

 var test = context.Set<SomeModel>().Include(e => e.Blob).ToList();
  

SQL:

   SELECT [e].[Id], [e].[OtherProperty], [e].[Id], [e].[Blob]
  FROM [SomeModel] AS [e]
  

(второе e.Id в select выглядит странно, но я думаю, мы можем с этим смириться)

Комментарии:

1. Приятно видеть, что я могу настроить это с помощью CodeFirst. Но наш процесс разработки в основном ориентирован на DB First, поэтому я не вижу, смогу ли я заставить EF Core scaffold вывести это разделение таблицы. Существует ли документ, описывающий соглашения, которые EF Core scaffold использует для создания своих таблиц, поскольку до сих пор мне везло в том, что он строит то, что кажется отношениями, которые я хотел, — но это вызывает беспокойство, генерируя беглый код, отличный от того, который я сгенерировал бы вручную.

2. Я не думаю, что стандартный каркас EF Core допускает настройку. Вы можете попробовать EF Core Power Tools или создание каркасов Entity Framework Core с помощью Handlebars