我有一个具有二进制字段的EF Core模型
class SomeModel {
string Id;
string otherProperty;
byte[] blob;
};
通常,当我查询数据库时,我想返回此模型的列表 - 然后,在后续调用中,只查询单个实体,但返回blob。
我无法在数据或代码中看到一种方法,以防止EF Core总是支付检索blob字段的成本。
我真的希望能够说出类似的话:
var list = await Context.SomeModels.ToListAsync();
// later
var item = await Context.SomeModels
.Where(m=>m.Id==someId)
.Include(m=>m.blob)
.FirstOrDefaultAsync();
我想我可能不得不把blob放到第二个表中,所以我可以强制一个可选的连接。
获得单独加载的唯一方法是将数据移动到具有一对一关系的单独实体。
但它不需要是一个单独的表。虽然最自然的选择看起来是owned entity,但由于拥有的实体总是被所有者加载,它必须是一个常规实体,但配置有table splitting - 简单来说,与主体实体共享同一个表。
将它应用于您的样品:
模型:
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
看起来很奇怪,但我想我们可以忍受这种情况)