我有一个简单的模型和一个简单的查询。我试图让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属性,但是作为第二个查询。
我四处寻找并应用了我发现的每一个修复:
Include()
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知道这可以通过一个查询完成?
编辑2: This question似乎解决了同样的问题,但只说调用Include()
修复了它,这在我的情况下无效。
答案 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();