2014-09-04 80 views
3

我有一个简单的模型和一个简单的查询。我试图让EF跃跃欲试负荷我的导航性能:实体框架在使用Include()时并不急切加载

// 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. 删除virtual来自导航性能

任何想法是怎么回事打个电话?是否有可能强制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,EF知道这可以通过一个查询来完成?

编辑2:This question似乎为解决同样的问题,但只规定调用Include()修复它,这是不是在我的情况下工作。

+0

它不是急切加载*'DocType' *?或者它是否不急于加载“DocType.Documents”,如您的评论中所述? – 2014-09-04 04:45:29

+0

查询的结果是'Document'的填充集合,'DocType'属性设置为'null'。当我检查正在执行的SQL时,查询中不包含有关“DocType”的任何内容,并且没有执行后续SQL来检索该数据。 – 2014-09-04 04:47:51

+0

我不禁进一步,但我已经使用EF多年,从未见过这种行为。我希望你找到一个解决方案。 – 2014-09-04 04:50:40

回答

-1

要包括导航属性我使用此语法(具有在包含引号):

context.Documents.Where(d => d.Id == ID)。包括(“DocType”) .SingleOrDefault();

+0

你是说用字符串代替表达式更好?不知何故,这种感觉就是失败了将表情作为选项的目的。 – 2014-09-04 05:15:57

+0

我不是在说什么是最好的或不是。我只是说什么代码适合我。 – VanRaidex 2014-09-04 05:20:41

0

在一般情况下,使用字符串而不是表达式(如提到@vanraidex)不是一个好的做法。一般情况下。但是,当使用第三方提供者(例如Oracle提供者)时,它可以是获得正确的sql(带连接)的唯一方法。

因此,如果您使用特殊的数据提供程序和.Include()方法不起作用,请尝试使用字符串而不是表达式。

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