2011-09-26 116 views
2

大家早上好,实体框架4:多对多关系IQueryable而不是ICollection

我想解决一个我首先遇到的EF代码问题。我的模式是以下

public class Article : IUrlNode 
{ 
    [Key] 
    public Guid ArticleID { get; set; } 
    public string Title { get; set; } 
    public DateTime DateCreated { get; set; } 
    public DateTime DateUpdated { get; set; } 
    public string Summary { get; set; } 
    [System.ComponentModel.DataAnnotations.InverseProperty("CategoryArticles")] 
    public virtual IQueryable<Category> ArticleCategories { get; set; } 

    public string FriendlyUrl 
    { 
     get; 
     set; 
    } 
} 
    [RouteChild("CategoryArticles")] 
    public class Category : ContentNode 
{ 
    public Guid ServiceId { get; set; } 

    [System.ComponentModel.DataAnnotations.InverseProperty("ArticleCategories")] 
    public virtual IQueryable<Article> CategoryArticles { get; set; } 
} 

我已经写了与我能够从数据库中检索类别,而不实际知道它的类别代码。从那时起,我必须在不知道它的文章的情况下再次检索该类别的单个文章。对于类别,我依赖于ContentNode基类和IUrlNode接口上的Articles。

分类检索工作正常,并用一个单一的查询,但之后我真正得到我不得不使用反射来获取由RouteChild指向的导航属性的种类属性找到适合我的标准的单篇文章。问题是导航属性类型为ICollection的,这意味着它会在最佳使用延迟加载,并把所有从数据库中的文章,并找到一个我在内存中寻找。

我的问题也正是在这以前的帖子(不是我)描述:

Entity Framework Code First IQueryable

有没有办法有一个导航财产的IQueryable或其他一些设计,可以绕过这个限制?

+0

你能创建一个新的可查询呢?即使用文章ID从上下文开始新的查询,您可以从中导航?希望这是有道理的... – Smudge202

回答

4

没有没有办法有导航财产IQueryable,但你可以通过收集改为IQueryable

IQueryable<Article> query = context.Entry(category).Collection(c => c.articles).Query(); 
query.Where(...).Load(); 

一般的“算法”看起来很奇怪。你想使用基类,但在同一时间你想访问子属性。这听起来不对,它可能更好地解决(非“通用”的方式也更好)。

+0

我会看看你的建议。这一点的关键是能够在不同类型的树上有节点。一个类别就是这些类型之一。我打破树并把文章放在它之外,因为我期望有很多文章。 – John

+0

是的,效果很好!还发现ObjectContext.GetObjectType真的很有用。谢谢! – John