2012-12-07 59 views
0
public class MyDbContext: DbContext 
{ 
} 
public class Product 
{ 
    public long Id {get; set;} 

    public long CategoryId {get; set;} 

    [ForeignKey("CategoryId")] 
    public virtual Category Category {get; set;} 
} 
public class Category 
{ 
    public long Id {get; set;} 
    public string Name {get; set;} 
} 

List<Product> GetProducts() 
{ 
    var context = new MyDbContext(); 
    var products = context.Set<Product>().ToList(); 
    var categories = context.Set<Category>().ToList(); 
    foreach(var product = in products) 
    { 
     product.Category = categories.First(c => c.Id == product.CategoryId); 
    } 

    return products; 
} 

在这里,我想检索所有具有最佳性能的关联类别的产品。 我第一次尝试延迟加载,但它导致了许多数据库查询。然后我使用急切的加载,但生成的查询脚本并不那么高效,特别是对于复杂的查询。所以我用下面的方法:明确加载导航属性

  • 得到所有产品,

  • 得到所有类别和

  • 产品的导航属性“类别”手动设置来自取出类别

我的问题是:

- 即使在我手动设置后,EF仍会延迟加载导航属性“Category”?

- 是否有更好的解决方案来加快复杂查询的加载速度?

+0

你真的不需要明确地说明。更改跟踪自动修复您的依赖关系。看到我的一些问题,但它也包括你需要的东西:http://stackoverflow.com/questions/17766211/how-to-do-linq-many-to-many-join-with-or-without- navigation-properties/20554719#20554719 –

回答

4

你得到最好的结果,如果你使用Include

var products = context.Set<Product>().Include("Category"); 

这将加载产品及其类别,一个查询和类别属性将不会触发延迟加载了。

更好的是扩展方法Includecontext.Set<Product>().Include(p => p.Category);

+0

对于简单的查询,使用预先加载没有问题。但是,如果实体对象有很多嵌套层次并且关系很复杂,那么由于许多表连接在一起,所以查询速度很慢。这就是我尝试以这种方式显式加载数据的原因。 – user1012036

+0

但是,如果这是您主要关心的问题,那么您应该更复杂一些。对于你显示的例子,Include就是这种方式。大拇指的规则是在一个声明中不应该多于树包含。对于复杂的查询很难给出进一步的一般建议。这真的取决于情况。 –