【问题标题】:EF4 Include() with Projection带有投影的 EF4 Include()
【发布时间】:2011-01-02 20:33:42
【问题描述】:

我正在尝试进行一个简单的查询,该查询既涉及急切加载又涉及投影,但遇到了问题。我正在使用 CodeFirst CTP5,但我相信这个问题也会直接影响 EF4。

这是我的初始查询:

public List<ArticleSummary> GetArticles()
    {
        var articlesQuery = _db.Articles.Include(article => article.Category).Select(article => new ArticleSummary
        {
            Article = article,
            CommentsCount = article.Comments.Count
        });

        return articlesQuery.ToList();
    }

这导致文章的类别属性为空。如果我取出投影,它工作得很好。看了this后,似乎提示我需要在投影后做include,所以我把查询改成:

    public List<ArticleSummary> GetArticles()
    {
        var articlesQuery = _db.Articles.Select(article => new ArticleSummary
        {
            Article = article,
            CommentsCount = article.Comments.Count
        });

        articlesQuery = articlesQuery.Include(x => x.Article.Category);

        return articlesQuery.ToList();
    }

这会导致类似于this SO post 的异常(见下文)。

"无法转换类型 'System.Linq.IQueryable1' to type 'System.Data.Objects.ObjectQuery1'。 LINQ to Entities 仅支持强制转换 实体数据模型基元类型。”

那么,我该怎么做呢?

【问题讨论】:

    标签: entity-framework linq-to-entities


    【解决方案1】:

    你可以试试:

    public List<ArticleSummary> GetArticles()
    {
        var articlesQuery = _db.Articles.Select(article => new
            {
                Article = article,
                Category = article.Category
                CommentsCount = article.Comments.Count
            }
        ).ToList().
        Select(
           x => new ArticleSummary() 
           {
                Article = x.Article,
                CommentsCount = x.CommentsCount
           }
        );
    
        return articlesQuery.ToList();
    }
    

    【讨论】:

    • 谢谢,这非常适合我显示的简化代码。实际上,在这个阶段我没有执行 ToList(),而是将 IQueryable 传递到 PagedList 构造函数中,该构造函数将 Take() 和 Skip() 添加到查询中并实际执行它。我当然可以重新排列查询,所以我不在第一部分执行 ToList(),创建一个临时实体而不是匿名类型,然后执行 PagedList 的东西,最后将 PagedList 转换为 PageList 但这是不理想。还有其他选择吗?
    • @zaph0d:您可以将 Category 添加到 ArticleSummary 类,因此您不需要使用 TempArticleSummary 类。那不会有伤害吧?
    • 是的,这样会更干净,这就是我现在要做的,非常感谢您的帮助。我不喜欢以这种方式污染我的模型,所以可以尝试让 EF4 大师 Julie Lerman 来看看。
    • @zaph0d:真的有污染吗?我不这么认为。至少你知道真正加载了什么。如果 Category 不直接在 ArticleSummary 类中,您将无法确定 Article 的哪些导航属性被加载。
    • 现在您在模型上有两个 Category 属性,其中一个是 null ,这有点令人困惑。我打算始终加载某些属性,例如类别,并且任何不总是存在的属性都将被标记为虚拟,因此它们可以被延迟加载。这样一来,您就可以随时访问我认为不错的每个属性?
    猜你喜欢
    • 1970-01-01
    • 2022-08-03
    • 2019-03-02
    • 2014-05-11
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多