简体   繁体   English

使用Include()时,实体框架不会急于加载

[英]Entity Framework does not eager load when using Include()

I have a simple model and a simple query. 我有一个简单的模型和一个简单的查询。 I'm trying to get EF to eager load my navigation properties: 我正试图让EF急切加载我的导航属性:

// Document object has a navigation property "DocType" of type DocType
// DocType object has a navigation property "Documents" of type ICollection<Documents> that is NOT virutal

context.Set<Document>().Where(d=>d.Id == id).Include(d=>d.DocType).SingleOrDefault();

The problem is that this doesn't actually eager load DocType . 问题是这实际上并不急于加载DocType The stranger thing is that excluding the Include() call does load the DocType property, but as a second query. 更奇怪的是, 排除 Include()调用会加载 DocType属性,但作为第二个查询。

I've looked all around and applied every fix I found: 我环顾四周并应用了我发现的每个修复:

  1. Added a call to Include() 添加了对Include()的调用
  2. Removed virtual from both navigation properties 从两个导航属性中删除了virtual

Any idea what's going on here? 知道这里发生了什么吗? Is it possible to coerce EF to merge this into a single query that's eager loaded? 是否有可能强制EF将其合并为一个急切加载的查询?

EDIT: This is my data model: 编辑:这是我的数据模型:

namespace Data.Models {

    class Document {
        public int Id { get; set;}
        public int TypeId { get; set; }
        public DocType DocType { get; set; }
    }

    class DocType {
        public int Id { get; set; }
        public string FullName { get; set; }
        public ICollection<Document> Documents { get; set; }
    }
}

namespace Data.Mappings {

    internal class DocumentTypeConfiguration : EntityTypeConfiguration<Document> {

        public DocumentTypeConfiguration() {
            ToTable("ProsDocs");

            HasKey(m => m.Id);

            Property(m => m.Id)
                .HasColumnName("ProsDocId")
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

            Property(m => m.TypeId)
                .HasColumnName("ProsDocTypeId")
                .HasMaxLength(3);

            HasRequired(d => d.DocType)
                .WithMany(dt=>dt.Documents)
                .WithForeignKey(d=>d.TypeId);
        }
    }

    internal class DocTypeTypeConfiguration : EntityTypeConfiguration<DocType> {

        public DocTypeTypeConfiguration() {
            ToTable("DocType");

            HasKey(m => m.Id);

            Property(m => m.Id)
                .HasColumnName("DocTypeId")
                .HasMaxLength(4);

            Property(m => m.FullName)
                .HasColumnName("DocTypeDesc")
                .HasMaxLength(255);
        }
    }
}

The oddest thing is that when I call: 最奇怪的是,当我打电话时:

context.Set<Document>().Find(id);

The DocType properties are populated, but EF does this by executing two separate queries. 将填充DocType属性,但EF通过执行两个单独的查询来执行此操作。 Is it possible to design this in such a way the EF understands that this can be accomplished with one query? 有可能以这样的方式设计这个,EF知道这可以通过一个查询完成吗?

EDIT 2: This question seems to address the same problem, but only states the calling Include() fixes it, which is not working in my case. 编辑2: 这个问题似乎解决了同样的问题,但只说调用Include()修复它,这在我的情况下不起作用。

To include navigation properties I use this syntax (with quotes in the Include): 要包含导航属性,我使用此语法(包括在Include中):

context.Documents.Where(d=>d.Id == id). context.Documents.Where(d => d.Id == id)。 Include("DocType") .SingleOrDefault(); 包含(“ DocType ”)。 SingleOrDefault();

In general case, using string instead of expression (as mention @vanraidex) is not a good practice. 一般情况下,使用字符串而不是表达式(如提及@vanraidex)不是一个好习惯。 In general case. 一般情况下。 However, when using third party providers (eg Oracle Provider) it can be the only way to get correct sql (with joins). 但是,在使用第三方提供程序(例如Oracle提供程序)时,它可能是获取正确sql(使用连接)的唯一方法。

So, if you using special Data Provider and .Include() method doesn't work, try to use string instead of expression. 因此,如果使用特殊的Data Provider和.Include()方法不起作用,请尝试使用string而不是expression。

context.Documents.Where(d=>d.Id == id).Include("DocType").SingleOrDefault();

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

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