Aneef
Aneef

Reputation: 3729

Entity Framework Fetch count of child entities as a property

I have 2 entities which depict Post, and Comments.

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
}

Now I want the NumberOfComments property to be populated with the actual count of comments of the post.

I cannot simply return p.Comments.Count; as the property definition as I'm not including the comments during the query. I only wants the count of the comments, not the whole collection in memory.

Upvotes: 3

Views: 2684

Answers (2)

fmdavid
fmdavid

Reputation: 95

This is the way I have found to do it.

The following classes would be necessary:

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
}

Do not add the PostExtraData class to the context.

And in the controller we wrote the following (in this case, to obtain the list of posts):

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

Upvotes: 3

Aar&#243;nBC.
Aar&#243;nBC.

Reputation: 1330

Suposing you always retrieve the Comments navigation you could do something like the following:

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;
        }
    }
}

About this line... return this.Comments?.Count() ?? 0;

Here we're using two null operators, the Null Conditional Operator ? and the Null Coalescing Operator ??.

The first one avoids the code to raise an error if the Comments property is null by immediately returning the value null before calling .Count(), the second operates when the left expression is null returns the right expression, so if this.Comments?.Count() returns null it'll give you 0.

Upvotes: -1

Related Questions