In my project I have types Comment and CommentDto:
public class Comment
{
    public Guid CommentId { get; set; }
    public string Content { get; set; }
    public Guid PostId { get; set; }
    public virtual Post Post { get; set; }
    public Guid? ParentCommentId { get; set; }
    public virtual Comment ParentComment { get; set; }
    public virtual ICollection<Comment> InverseParentComment { get; set; }
}
class CommentDto
{
    public Guid CommentId { get; set; }
    public string Content { get; set; }
    public Guid? ParentCommentId { get; set; }
    public ICollection<CommentDto> InverseParentComment { get; set; }
}
Comment will be mapped into CommentDto. Here is the configuration:
cfg.CreateMap<Comment, CommentDto>();
I have the following recursive CTE, encapsulated inside of table-valued Function:
FUNCTION [dbo].[fn_PostCommentHierarchy] (@postId UNIQUEIDENTIFIER)
RETURNS TABLE
AS
RETURN
(
    WITH cte AS
    (
        SELECT CommentId, Content, PostId, ParentCommentId 
        FROM dbo.Comment
        WHERE ParentCommentId IS NULL and PostId = @postId
        UNION ALL
        SELECT child.CommentId, child.Content, child.PostId, child.ParentCommentId
        FROM dbo.Comment child
        INNER JOIN cte parent
        ON parent.CommentId = child.ParentCommentId
        WHERE parent.PostId = @postId
    )
    SELECT * FROM cte
);
This function allows to get the hierarchy of comments of the given post (it takes the ID of a post).
There are comments stored in the database:

To make it more readable, I represent it in hierarchically order (only Content property):
- Hello World!
- Are you a programmer?
- Sure
- What?
 
 
- Are you a programmer?
- I wanna go to Mars too!
- See you on the Moon :)
 
Call function fn_PostCommentHierarchy using EF Core
List<Comment> commentHierarchy = await _context.Comment
    .FromSqlInterpolated($"SELECT CommentId, Content, PostId, ParentCommentId FROM dbo.fn_PostCommentHierarchy('post-id-here')")
    .ToListAsync();
EF Core sends the following SQL-query to SQL-Server:
SELECT CommentId, Content, PostId, ParentCommentId FROM dbo.fn_PostCommentHierarchy('post-id-here')
The code above works as expected (JSON-format was used to increase the readability):
[
{
    "commentId": "be02742a-9170-4335-afe7-3c7c22684424",
    "content": "Hello World!",
    "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
    "post": null,
    "parentCommentId": null,
    "parentComment": null,
    "commentRates": [],
    "inverseParentComment": [
    {
        "commentId": "59656765-d1ed-4648-8696-7d576ab7419f",
        "content": "Are you a programmer?",
        "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
        "post": null,
        "parentCommentId": "be02742a-9170-4335-afe7-3c7c22684424",
        "commentRates": [],
        "inverseParentComment": [
        {
            "commentId": "0bb77a43-c7bb-482f-9bf8-55c4050974da",
            "content": "Sure",
            "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
            "post": null,
            "parentCommentId": "59656765-d1ed-4648-8696-7d576ab7419f",
            "commentRates": [],
            "inverseParentComment": []
        },
        {
            "commentId": "b8d61cfd-d274-4dae-a2be-72e08cfa9066",
            "content": "What?",
            "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
            "post": null,
            "parentCommentId": "59656765-d1ed-4648-8696-7d576ab7419f",
            "commentRates": [],
            "inverseParentComment": []
        }
        ]
    }
    ]
},
{
    "commentId": "cfe126b3-4601-4432-8c87-445c1362a225",
    "content": "I wanna go to Mars too!",
    "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
    "post": null,
    "parentCommentId": null,
    "parentComment": null,
    "commentRates": [],
    "inverseParentComment": [
    {
        "commentId": "ab6d6b49-d772-48cd-9477-8d40f133c37a",
        "content": "See you on the Moon :)",
        "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
        "post": null,
        "parentCommentId": "cfe126b3-4601-4432-8c87-445c1362a225",
        "commentRates": [],
        "inverseParentComment": []
    }
    ]
},
{
    "commentId": "ab6d6b49-d772-48cd-9477-8d40f133c37a",
    "content": "See you on the Moon :)",
    "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
    "post": null,
    "parentCommentId": "cfe126b3-4601-4432-8c87-445c1362a225",
    "parentComment": {
        "commentId": "cfe126b3-4601-4432-8c87-445c1362a225",
        "content": "I wanna go to Mars too!",
        "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
        "post": null,
        "parentCommentId": null,
        "parentComment": null,
        "commentRates": [],
        "inverseParentComment": []
    },
    "commentRates": [],
    "inverseParentComment": []
},
{
    "commentId": "59656765-d1ed-4648-8696-7d576ab7419f",
    "content": "Are you a programmer?",
    "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
    "post": null,
    "parentCommentId": "be02742a-9170-4335-afe7-3c7c22684424",
    "parentComment": {
        "commentId": "be02742a-9170-4335-afe7-3c7c22684424",
        "content": "Hello World!",
        "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
        "post": null,
        "parentCommentId": null,
        "parentComment": null,
        "commentRates": [],
        "inverseParentComment": []
    },
    "commentRates": [],
    "inverseParentComment": [
    {
        "commentId": "0bb77a43-c7bb-482f-9bf8-55c4050974da",
        "content": "Sure",
        "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
        "post": null,
        "parentCommentId": "59656765-d1ed-4648-8696-7d576ab7419f",
        "commentRates": [],
        "inverseParentComment": []
    },
    {
        "commentId": "b8d61cfd-d274-4dae-a2be-72e08cfa9066",
        "content": "What?",
        "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
        "post": null,
        "parentCommentId": "59656765-d1ed-4648-8696-7d576ab7419f",
        "commentRates": [],
        "inverseParentComment": []
    }
    ]
},
{
    "commentId": "0bb77a43-c7bb-482f-9bf8-55c4050974da",
    "content": "Sure",
    "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
    "post": null,
    "parentCommentId": "59656765-d1ed-4648-8696-7d576ab7419f",
    "parentComment": {
        "commentId": "59656765-d1ed-4648-8696-7d576ab7419f",
        "content": "Are you a programmer?",
        "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
        "post": null,
        "parentCommentId": "be02742a-9170-4335-afe7-3c7c22684424",
        "parentComment": {
            "commentId": "be02742a-9170-4335-afe7-3c7c22684424",
            "content": "Hello World!",
            "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
            "post": null,
            "parentCommentId": null,
            "parentComment": null,
            "commentRates": [],
            "inverseParentComment": []
        },
        "commentRates": [],
        "inverseParentComment": [
        {
            "commentId": "b8d61cfd-d274-4dae-a2be-72e08cfa9066",
            "content": "What?",
            "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
            "post": null,
            "parentCommentId": "59656765-d1ed-4648-8696-7d576ab7419f",
            "commentRates": [],
            "inverseParentComment": []
        }
        ]
    },
    "commentRates": [],
    "inverseParentComment": []
},
{
    "commentId": "b8d61cfd-d274-4dae-a2be-72e08cfa9066",
    "content": "What?",
    "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
    "post": null,
    "parentCommentId": "59656765-d1ed-4648-8696-7d576ab7419f",
    "parentComment": {
        "commentId": "59656765-d1ed-4648-8696-7d576ab7419f",
        "content": "Are you a programmer?",
        "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
        "post": null,
        "parentCommentId": "be02742a-9170-4335-afe7-3c7c22684424",
        "parentComment": {
            "commentId": "be02742a-9170-4335-afe7-3c7c22684424",
            "content": "Hello World!",
            "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
            "post": null,
            "parentCommentId": null,
            "parentComment": null,
            "commentRates": [],
            "inverseParentComment": []
        },
        "commentRates": [],
        "inverseParentComment": [
        {
            "commentId": "0bb77a43-c7bb-482f-9bf8-55c4050974da",
            "content": "Sure",
            "postId": "69f3ca3a-66fc-4142-873d-01e950d83adf",
            "post": null,
            "parentCommentId": "59656765-d1ed-4648-8696-7d576ab7419f",
            "commentRates": [],
            "inverseParentComment": []
        }
        ]
    },
    "commentRates": [],
    "inverseParentComment": []
}]Note: I made bold comments, that don't have a parent (root comments).
Map Comment into CommentDto
The code above works with entity-type Comment, but I want to map it into CommentDto. So, let's use ProjectTo for this purpose:
List<CommentDto> commentHierarchy = await _context.Comment
    .FromSqlInterpolated($"SELECT CommentId, Content, PostId, ParentCommentId FROM dbo.fn_PostCommentHierarchy('post-id-here')")
    .ProjectTo<CommentDto>(_mapper.ConfigurationProvider)
    .ToListAsync();
Note: _mapper is an object of type IMapper.
I think, the result should be similar to the result, that I got before using ProjectTo. But it looks like:
[
{
    "commentId": "be02742a-9170-4335-afe7-3c7c22684424",
    "content": "Hello World!",
    "parentCommentId": null,
    "inverseParentComment": [
    {
        "commentId": "59656765-d1ed-4648-8696-7d576ab7419f",
        "content": "Are you a programmer?",
        "parentCommentId": "be02742a-9170-4335-afe7-3c7c22684424",
        "inverseParentComment": null
    }
    ]
},
{
    "commentId": "cfe126b3-4601-4432-8c87-445c1362a225",
    "content": "I wanna go to Mars too!",
    "parentCommentId": null,
    "inverseParentComment": [
    {
        "commentId": "ab6d6b49-d772-48cd-9477-8d40f133c37a",
        "content": "See you on the Moon :)",
        "parentCommentId": "cfe126b3-4601-4432-8c87-445c1362a225",
        "inverseParentComment": null
    }
    ]
},
{
    "commentId": "0bb77a43-c7bb-482f-9bf8-55c4050974da",
    "content": "Sure",
    "parentCommentId": "59656765-d1ed-4648-8696-7d576ab7419f",
    "inverseParentComment": []
},
{
    "commentId": "b8d61cfd-d274-4dae-a2be-72e08cfa9066",
    "content": "What?",
    "parentCommentId": "59656765-d1ed-4648-8696-7d576ab7419f",
    "inverseParentComment": []
},
{
    "commentId": "59656765-d1ed-4648-8696-7d576ab7419f",
    "content": "Are you a programmer?",
    "parentCommentId": "be02742a-9170-4335-afe7-3c7c22684424",
    "inverseParentComment": [
    {
        "commentId": "0bb77a43-c7bb-482f-9bf8-55c4050974da",
        "content": "Sure",
        "parentCommentId": "59656765-d1ed-4648-8696-7d576ab7419f",
        "inverseParentComment": null
    },
    {
        "commentId": "b8d61cfd-d274-4dae-a2be-72e08cfa9066",
        "content": "What?",
        "parentCommentId": "59656765-d1ed-4648-8696-7d576ab7419f",
        "inverseParentComment": null
    }
    ]
},
{
    "commentId": "ab6d6b49-d772-48cd-9477-8d40f133c37a",
    "content": "See you on the Moon :)",
    "parentCommentId": "cfe126b3-4601-4432-8c87-445c1362a225",
    "inverseParentComment": []
}
]Note: I made bold comments, that don't have a parent (root comments).
Compare the result before using ProjectTo and after. Why they are different?
For the code above EF Core sends the following SQL-query to SQL-server:
SELECT [c].[CommentId], [c].[Content], [c].[ParentCommentId], [c0].[CommentId], [c0].[Content], [c0].[ParentCommentId]
FROM (
    SELECT CommentId, Content, PostId, ParentCommentId FROM dbo.fn_PostCommentHierarchy('69f3ca3a-66fc-4142-873d-01e950d83adf')
) AS [c]
LEFT JOIN [Comment] AS [c0] ON [c].[CommentId] = [c0].[ParentCommentId]
ORDER BY [c].[CommentId], [c0].[CommentId]
Questions
Why the result before using ProjectTo and the result after using ProjectTo are not the same?
How to fix this problem?
Update 1
According to Svyatoslav Danyliv:
Recursive CTE returns flat list, then you have to build hierarchy again.
But why in this case I should use recursive CTE?
The following solution works in the same way:
List<CommentDto> commentFlatList = await _context.Comment
    .Where(c => c.PostId == Guid.Parse("post-id-here"))
    .ProjectTo<CommentDto>(_mapper.ConfigurationProvider)
    .ToListAsync();
                
Dictionary<Guid, CommentDto> commentDictionary = commentFlatList
    .ToDictionary(c => c.CommentId);
foreach (var comment in commentFlatList)
{
    if (comment.ParentCommentId == null)
    {
        continue;
    }
    if (commentDictionary.TryGetValue((Guid) comment.ParentCommentId, out CommentDto parent))
    {
        parent.Children.Add(comment);
    }
}
List<CommentDto> commentHierarchy = commentFlatList.Where(c => c.ParentCommentId == null);
Note: I used Dictionary instead of Lookup (see this example), but it doesn't change the idea.
Update 2
Let's have a look at the code from the Update 1:
List<CommentDto> commentFlatList = await _context.Comment
        .Where(c => c.PostId == Guid.Parse("post-id-here"))
        .ProjectTo<CommentDto>(_mapper.ConfigurationProvider)
        .ToListAsync();
It will be translated by EF Core into the following:
exec sp_executesql N'SELECT [c].[CommentId], [c].[Content], [c].[ParentCommentId]
FROM [Comment] AS [c]
WHERE [c].[PostId] = @__request_PostId_0',N'@__request_PostId_0 uniqueidentifier',@__request_PostId_0='post-id-here'
 
                        
Recursive CTE returns flat list, then you have to build hierarchy again.