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

时间:2014-09-04 04:33:39

标签: c# entity-framework entity-framework-6

我有一个简单的模型和一个简单的查询。我试图让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();

问题在于,这实际上并不急于加载DocType。更奇怪的是排除 Include()调用确实加载了 DocType属性,但是作为第二个查询。

我四处寻找并应用了我发现的每一个修复:

  1. 添加了对Include()
  2. 的致电
  3. 从两个导航属性中删除了virtual
  4. 知道这里发生了什么吗?是否有可能强制EF将其合并为一个急切加载的查询?

    编辑:这是我的数据模型:

    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);
            }
        }
    }
    

    最奇怪的是,当我打电话时:

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

    填充DocType属性,但EF通过执行两个单独的查询来执行此操作。是否有可能以这样的方式设计它,EF知道这可以通过一个查询完成?

    编辑2: This question似乎解决了同样的问题,但只说调用Include()修复了它,这在我的情况下无效。

2 个答案:

答案 0 :(得分:0)

要包含导航属性,我使用此语法(包含在Include中):

context.Documents.Where(d =&gt; d.Id == id)。包含(&#34; DocType&#34;) .SingleOrDefault();

答案 1 :(得分:0)

一般情况下,使用字符串而不是表达式(如提及@vanraidex)不是一个好习惯。一般情况下。但是,在使用第三方提供程序(例如Oracle提供程序)时,它可能是获取正确sql(带连接)的唯一方法。

因此,如果您使用特殊的Data Provider和.Include()方法不起作用,请尝试使用string而不是表达式。

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