繁体   English   中英

从EF核心获取实体而不加载所有字段

[英]Get an entity from EF core without loading all fields

假设我有一个这样的模型:

public class Model {
    [Key]
    public int Id { get; set; }
    public string SmallData { get; set; }
    public byte[] VeryLargeBlob { get; set; }
}

我需要从数据库读取一个实体,并且仅使用字段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}\" }}" );
        }
    }

结果:

在此处输入图片说明

数据库中的表:

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM