首页 > 解决方案 > EF Core - 不包括二进制字段

问题描述

我有一个具有二进制字段的 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 放入第二个表中,以便我可以强制进行可选连接。

标签: entity-frameworkef-core-2.0

解决方案


获得单独加载的唯一方法是将数据移动到具有一对一关系的单独实体。

不过,它不需要是单独的表。虽然最自然的选择看起来是自有实体,因为自有实体总是加载所有者,它必须是一个常规实体,但配置了表拆分- 简单来说,与主体实体共享同一个表。

将其应用于您的样本:

模型:

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很奇怪,但我想我们可以忍受)


推荐阅读