【问题标题】:Entity Framework Fetch count of child entities as a property实体框架获取子实体的计数作为属性
【发布时间】:2016-11-21 17:45:23
【问题描述】:

我有 2 个描述 PostComments 的实体。

public class Post
{
    public int Id { get; set; }
    public ICollection<Comment> Comments { get; set; }

    //other properties 


    //Unmapped property
    public int NumberOfComments { get; set; }

}

public class Comment
{
    public int Id { get; set; }
    public Post Post { get; set; }
    public int PostId { get; set; }

    // other properties
}

现在我希望 NumberOfComments 属性填充帖子的实际 cmets 计数。

  • 尝试将查询结果投影到帖子集合中 模特没有锻炼。

  • 尝试加入表格,然后按帖子 ID 分组仍然没有 似乎有效。

我不能简单地将 return p.Comments.Count; 作为属性定义,因为我在查询期间不包括 cmets。我只想要 cmets 的计数,而不是内存中的整个集合。

【问题讨论】:

  • public int NumberOfComments { get { return Comments.Count(); } } ?
  • 我不包括 cmets。我只想获取 cmets 的数量。
  • 我认为您必须在查询中明确请求它select new Post { Id = p.Id, NumberOfComments = p.Comments.Count()}?
  • juharr 谢谢。但它会抛出“无法在 linq 到实体查询中构造实体”
  • @Aneef 然后就做类似... select new { Id= p.Id, NumberOfComments = p.Comments.Count() }).AsEnumerable().Select(p =&gt; new Post { Id = p.Id, NumberOfComments = p.NumberOfComments}) 的事情。或者考虑为您要使用的特定数据创建一个单独的 DTO,并将您的其他层与您的实体分开。

标签: c# sql entity-framework entity-framework-6


【解决方案1】:

这是我发现的方法。

以下类是必要的:

public class PostExtraData
{
    public Post post { get; set; }
    public int NumberOfComments { get; set; } 
}

public class Post
{
    public int Id { get; set; }
    public ICollection<Comment> Comments { get; set; }

    //other properties 

}

public class Comment
{
    public int Id { get; set; }
    public Post Post { get; set; }
    public int PostId { get; set; }

    // other properties
}

不要将PostExtraData 类添加到上下文中。

在控制器中,我们编写了以下内容(在这种情况下,获取帖子列表):

return _context.Post
       .Select(p => new PostExtraData
       {
           Post= p,
           NumberOfComments = p.Comments.Count(),
       })
       .ToList();

【讨论】:

    【解决方案2】:

    假设您总是检索评论导航,您可以执行以下操作:

    public class Post
    {
        public int Id { get; set; }
        public ICollection<Comment> Comments { get; set; }
    
        //other properties 
    
        //Unmapped property: Since it's value depends on the Comments collection
        //we don't need to define the setter. If the collection is null, it'll
        //return zero.
        public int NumberOfComments
        {
            get
            {
                return this.Comments?.Count() ?? 0;
            }
        }
    }
    

    关于这条线...return this.Comments?.Count() ?? 0;

    这里我们使用了两个空运算符,空条件运算符? 和空合并运算符??

    第一个通过在调用.Count()之前立即返回值null来避免代码在Comments属性为null时引发错误,第二个在左侧表达式为null时返回右侧表达式,因此如果this.Comments?.Count()返回 null 它会给你 0。

    【讨论】:

    • 在下面查看我的答案。它总是 0.bcoz 我并不总是检索 cmets
    • 请在 Matts 的回答中查看我的回复和 juharrs 的回复。我知道 ??运算符和导航属性。但只是与上述混淆
    • 好的,如果您不检索每个帖子的 cmets,也许您可​​以在另一个查询中单独进行计数(您必须将设置器返回到 NumberOfComments 属性)。 myPost.NumberOfComments =.db.Comments.Where(c => c.PostId == postId).Count();
    • 亚伦BC。我认为这不是一种有效的方式。
    • 对于生成的查询,我认为它会使用数据库中的 COUNT() sql 函数,因此它不会将数据检索到对象并稍后在内存中计数。 @Aneef
    【解决方案3】:

    您可以使用.Count() 获取cmets 的数量。

    public class Post
    {
        public int Id{ get; set; }
        public ICollection<Comment> Comments { get; set; }
    
        //other properties 
    
        //Unmapped property
        public int NumberOfComments { get { return Comments.Count(); } }
    
    }
    

    【讨论】:

    • 我不包括 cmets。我只想获取 cmets 的数量。
    • 不包括 cmets 是什么意思。它们是: public ICollection Comments { get;放; } - 这是你的代码不是吗?
    • @AlexeiFimine 在 EF 中,它并不总是提取表示为导航属性的所有相关表的所有数据。
    • 我不在查询中使用 db.Posts.Include(p=>p.Comments)。因此无法正确检索 cmets。所以 cmets.count 会在这里抛出错误??
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多