Entity framework 预加载和延迟加载

Entity framework Eager and Lazy load

试图找出实体框架中延迟加载和急切加载之间的区别。假设我有以下型号:

public interface IBaseEntityObject 
{
    public int Id {get; set;}
}


public abstract class BaseEntityObject : IBaseEntityObject
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id {get; set;}
}


public class Folder : BaseEntityObject
{   
    [DataMember]
    public string Name {get; set;}

    [DataMember]
    public virtual List<Letter> Letters {get; set;} 
}


public abstract class Letter : BaseEntityObject
{   
    [DataMember]
    public string Title {get; set;}

    [DataMember]
    public string Content {get; set;}

    public virtual Folder Folder {get; set;}

    [DataMember]
    public int FolderId {get; set;}

    [DataMember]
    public DateTime CreationDate {get; set;}
}

public class OutgoingLetter : Letter
{
    // .. OutgoingLetter properties
}

public class ReceviedLetter : Letter
{
    // .. ReceviedLetter properties
}


public class MyDbContext : DbContext
{
    public DbSet<Folder> Folders {get; set;}

    public DbSet<Letter> Letters {get; set;}


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Folder <-> Letters       
        modelBuilder.Entity<Letter>()
        .HasRequired(t => t.Folder)
        .WithMany(f => f.Letters)
        .HasForeignKey(t => t.FolderId)
        .WillCascadeOnDelete(true);
    }
}

每当我从数据库中请求一个文件夹时,它的主要目的是访问其中的字母。因此,最好是我已经从头加载它而不是在访问时调用另一个数据库字母 属性 我正确吗?

我读到禁用延迟加载是通过在 ctor 中配置它来完成的,方法是将 EnableLazyLoading 属性 设置为 false 并从字母列表中删除虚拟关键字。

如果我在请求文件夹时只使用 Include(x => x.Lettters) 并保持延迟加载启用,会有什么不同?启用延迟加载时不能使用include?

另外Letter模型中的Folder属性跟延迟加载有什么关系吗?我在索要信件时不使用文件夹,但我见过的大多数模型都包含一对多关系中的父亲 属性,我真的不明白为什么。

谢谢!

Whenever I ask a folder from the data base, it's main purpose is for accessing the Letters in it.. Therefore, will it be best if I already load it from the beginning instead of making another database call when accessing the Letters property am I correct?

是的,正确。

I've read that disabling the Lazy load is done by configuring it in the ctor with by setting the EnableLazyLoading property to false and removing virtual key word from the letters list.

如果您不想延迟加载某个 属性,请删除 virtual 关键字。如果您有时需要它而有时不需要,请在代码中创建新上下文时禁用延迟加载。

What would be the difference if I just use Include(x => x.Lettters) whenever I ask for a folder and keep the Lazy loading enabled? Include can not be used when Lazy loading is enabled?

它们对彼此没有影响。如果您不包含这些字母,并且您尝试访问 属性,EF 将再次调用 db 以获取它们(延迟加载),如果您包含它们,它们将可用并且无需额外调用数据库已创建。

Moreover is there any relation between the Folder property that is held in Letter model to the lazy loading? I don't use the Folder when asking for a letter, yet most models around I've seen contain the Father property in one to many relationship and I don't really understand why.

在大多数示例中,导航 属性 以两种方式定义,但如果您永远不需要从信件中获取文件夹,那么不在您的文件中定义 属性 是完全合理的字母模型。

I've read that disabling the Lazy load is done by configuring it in the ctor with by setting the EnableLazyLoading property to false and removing virtual key word from the letters list

两个都不聪明。这相当于为了关闭发动机而将电池从汽车中取出。

启用延迟加载并不意味着它已被使用,与虚拟相同

What would be the difference if I just use Include(x => x.Lettters) whenever I ask for a folder and keep the Lazy loading enabled?

以后可以使用延迟加载(破坏后不能使用)。

Include can not be used when Lazy loading is enabled?

谁说的?它完全可以——在这种情况下,延迟加载将不会对已经包含的元素发生,这让您可以根据具体情况自由选择延迟加载或不延迟加载。

您还可以在启用延迟加载的情况下使用 Include。不使用 Include 使代码更清晰,所以通常我只在遇到性能问题时才使用 Include。
此外,导航在项目生命周期中可能会发生变化,因此对于延迟加载,您无需记住它。
而且,你不能在序列化期间使用延迟加载,否则你可能会序列化所有数据库。

仅供参考,Include 还经常生成非常丑陋的查询(但我从未遇到过性能问题)。

关于父属性仅对导航有用(即您可以从一封信导航到一个文件夹,然后再导航到该文件夹​​的信件)。