c# - 从 EF 核心获取实体而不加载所有字段
问题描述
假设我有一个这样的模型:
public class Model {
[Key]
public int Id { get; set; }
public string SmallData { get; set; }
public byte[] VeryLargeBlob { get; set; }
}
我需要从数据库中读取实体并仅使用 field SmallData
,并且VeryLargeBlob
不需要。VeryLargeBlob
非常大(例如,几兆字节)并且从数据库中读取它会影响性能。
我知道我可以通过这种方式选择一些字段:
var data = context.Model.Where(m => m.Id == Id).Select(m => new { Id = m.Id, SmallData = m.SmallData }).FirstOrDefault();
但是我需要一个Model
实例而不是匿名对象,这样我就可以将它用于以后的查询。即使我破解它并使其返回一个Model
对象,该实例也不会被跟踪,并且不会与延迟加载兼容。
有没有办法只从模型中加载部分数据?
解决方案
使用“表拆分”在两个或多个实体类之间拆分单个表,允许您控制是否以及何时加载某些属性。通过为多个实体指定相同的表名并使用共享主键(依赖实体的 PK 是主体实体的 FK)来实现这一点。这是一个例子:
public class PrincipalEntity
{
[Key]
public int Id { get; set; }
public string PrincipalProperty { get; set; }
public virtual DependentEntity Dependent { get; set; }
}
public class DependentEntity
{
[Key]
public int Id { get; set; }
public string DependentProperty { get; set; }
}
public class PricipalEntityConfiguration : IEntityTypeConfiguration<PrincipalEntity>
{
public void Configure( EntityTypeBuilder<PrincipalEntity> builder )
{
//builder.HasKey( pe => pe.Id );
builder.HasOne( pe => pe.Dependent )
.WithOne()
.HasForeignKey<DependentEntity>( de => de.Id ); // FK is PK
builder.ToTable( "YourTableName" );
}
}
public class DependentEntityConfiguration : IEntityTypeConfiguration<DependentEntity>
{
public void Configure( EntityTypeBuilder<DependentEntity> builder )
{
//builder.HasKey( de => de.Id );
builder.ToTable( "YourTableName" ); // same table name
}
}
public class TestContext : DbContext
{
public DbSet<PrincipalEntity> PrincipalEntities { get; set; }
public DbSet<DependentEntity> DependentEntities { get; set; }
public TestContext( DbContextOptions options ) : base( options )
{
}
protected override void OnModelCreating( ModelBuilder modelBuilder )
{
modelBuilder.ApplyConfiguration( new PricipalEntityConfiguration() );
modelBuilder.ApplyConfiguration( new DependentEntityConfiguration() );
}
}
class Program
{
static void Main( string[] args )
{
var options = new DbContextOptionsBuilder<TestContext>()
.UseSqlServer( "Server=(localdb)\\mssqllocaldb;Database=EFCoreTest;Trusted_Connection=True;" )
.Options;
using( var dbContext = new TestContext( options ) )
{
var pEntity = new PrincipalEntity()
{
PrincipalProperty = "Principal Property Value",
Dependent = new DependentEntity()
{
DependentProperty = "Dependent Property Value",
},
};
dbContext.PrincipalEntities.Add( pEntity );
dbContext.SaveChanges();
}
using( var dbContext = new TestContext( options ) )
{
var pEntity = dbContext.PrincipalEntities
// eager load dependent
.Include( pe => pe.Dependent )
.Single();
System.Console.WriteLine( "Loaded Principal w/ Dependent Eager-Loaded:" );
DisplayValues( pEntity );
dbContext.Entry( pEntity.Dependent ).State = EntityState.Detached;
dbContext.Entry( pEntity ).State = EntityState.Detached;
pEntity = dbContext.PrincipalEntities.Single();
System.Console.WriteLine();
System.Console.WriteLine( "Load Principal Entity Only:" );
DisplayValues( pEntity );
// explicitly load dependent
dbContext.Entry( pEntity )
.Reference( pe => pe.Dependent )
.Load();
System.Console.WriteLine();
System.Console.WriteLine( "After Explicitly Loading Dependent:" );
DisplayValues( pEntity );
}
}
private static void DisplayValues( PrincipalEntity pe )
{
System.Console.WriteLine( $"Principal Entity = {{ Id: {pe.Id}, PrincipalProperty: \"{pe.PrincipalProperty}\" }}" );
if( null == pe.Dependent )
{
System.Console.WriteLine( "Principal Entity's Dependent property is null" );
}
else
{
System.Console.WriteLine( $"Dependent Entity = {{ Id: {pe.Dependent.Id}, DependentProperty: \"{pe.Dependent.DependentProperty}\" }}" );
}
}
结果:
数据库中的表:
推荐阅读
- angular - HttpClient 不发出 http 网络请求
- guidewire - 如何在策略中心创建自定义事件
- django - 如何使用 QuerySet 输出 CSV 文件
- spring-boot - 我正在尝试将 IBMMQ 与我的 Spring Boot 应用程序连接,但连接应该通过 spid(pki)。有人知道该怎么做吗?
- python - 自动编码器重建图像(输出)不清楚,因为我想要
- xslt - XSLT。将数字转换为印度格式
- c++ - 当类的成员存储为没有此类方法的父类的对象时,如何访问该类的成员?
- sonarqube - 如何在 sonarqube 中获取 scm 帐户搜索的代码行
- javascript - Bootstrap 手风琴在另一个打开时隐藏
- java - 调用 onClick 时出现“OutOfMemoryError”(崩溃报告)