#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