【问题标题】:EF 4.1 code-first: How to select an entity with it's collection-property's countEF 4.1 代码优先:如何选择具有集合属性计数的实体
【发布时间】:2011-09-26 18:42:52
【问题描述】:

我有一个名为 Tag 的实体,其导航属性(集合)名为 ArticlesTag 有一个名为 ArticleCount 的被忽略属性,用于保存关联的 Article 的计数(只是在运行中-时间并在视图中使用 - 忽略数据库)。见:

public class Tag{

    public int Id { get; set; }

    public int Title { get; set; }

    public virtual ICollection<Article> Articles { get; set; }

    [NotMapped]
    public int ArticleCount { get; set; }

}

如何在 ONE 查询中选择所有 Tag (或一个)以及它的 ArticleCount -in entity framework 4.1 code-first,带有 lambda 表达式好吗?

【问题讨论】:

    标签: lambda entity-framework-4.1 ef-code-first code-first navigation-properties


    【解决方案1】:
    var tagsAndCounts =  from tag in context.Tags
                         where ...
                         select new { tag, count = tag.Articles.Count() }
    var tagsWithCount = tagsAndCounts.ToList()
                                     .Select(x => 
                                             {
                                                 x.tag.ArticleCount = x.count;
                                                 return x.tag;
                                             };
    

    (我会以不同的方式设计 - ArticleCount 不应该是模型的一部分,或者它应该是 Articles 上的投影,您可以使用 Include() 进行预加载。但这可以满足您的需求)


    更新:我的设计。

    public class Tag
    {
       ...
       public int ArticleCount { get { return Articles.Count; } }
    }
    
    var tagsWithEagerLoadedArticles = context.Tags.Include(x => x.Articles)
                                             .Where(...).Etc();
    

    当然,这是否表现良好取决于每个标签的预期文章数。如果是几十个,这将合理地工作,同时比其他方法更清洁。如果是数百个,则另一个更好。

    现在,如果是这种情况,您应该使用匿名或命名的表示类型,而不是重用实体。

    【讨论】:

    • 这比我的解决方案写得更好!
    • 你能留下你的建议的例子吗?非常感谢。
    • 在我的情况下使用匿名更好;我以前用过那个设计(第二个);另外,我将ArticleCount 用作getter 属性并从缓存中读取它,但我正在寻找更好的方法。现在我认为您提供给我的第一个 code-sn-p 比其他所有代码都好。特别感谢。我接受你的 A。还有另一个 Q,我可以给你发个问题吗?如果你有时间?很抱歉将其留在这里,但在您的个人资料中没有任何邮件地址,并且 SOF 不为用户提供任何关系或联系。我的邮件:kavand.ds[at]gmail 如果您允许,我将非常感谢。致以最诚挚的问候。
    • 如果是技术问题,请在此处发布另一个问题。
    【解决方案2】:

    所有标签示例:

    var result = context.Tags
        .Select(t => new
        {
            Tag = t,
            ArticleCount = t.Articles.Count()
        });
    
    foreach (var a in result)
        a.Tag.ArticleCount = a.ArticleCount;
    
    var tags = result.Select(a => a.Tag).ToList();
    

    这只是一个查询,副本发生在内存中。我相信除了将ArticleCount从匿名结果对象复制到标签中之外别无他法,因为你不能直接投影到实体中,所以你不能使用Select(t =&gt; new Tag { ... });。您可以使用另一个 named 类型而不是匿名类型,但不能使用实体类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      • 2017-10-16
      相关资源
      最近更新 更多