简体   繁体   English

.Net 5 Entity Framework 从涉及 FK 1:M 关系的查询中删除不必要的调用

[英].Net 5 Entity Framework removing unneccessary calls from Query involving FK 1:M relationship

I have the following 2 DTOs that are used to return the information in the API in order to filter out fields that I don't want the client to be able to view我有以下 2 个 DTO,用于返回 API 中的信息,以便过滤掉我不希望客户端能够查看的字段

public record CommentDto
{
    public int? CommentId { get; set; }
    public string AuthorUid { get; set; }
    public string Text { get; set; }
    public int? ParentCommentId { get; set; }
    public string CommentPn { get; set; }
    public virtual UserDto User { get; set; }
}

public record UserDto
{
    public string Uid { get; set; }
    public string Username { get; set; }
}

I'm querying the postgres database using the following:我正在使用以下命令查询 postgres 数据库:

            var comments = await dbSet.
            Where(c => c.commentPn == sentPn)
           .Select(c => new CommentDto
            {
                CommentId = c.CommentId,
                CommentPn = c.CommentPn,
                AuthorUid = c.AuthorUid,
                Text = c.Text,
                ParentCommentId = c.ParentCommentId,
                User = new UserDto
                {
                    Username = dbSet.Select(u => u.User.Username).Single(),
                    Uid = dbSet.Select(u => u.User.Uid).Single()
                },
            }).ToListAsync();

While this works and the correct data is returned, I notice what I believe are unnecessary call(s) being included in the query.虽然这可行并且返回了正确的数据,但我注意到我认为查询中包含了不必要的调用。

  SELECT d1.comment_id AS "CommentId", d1.comment_pn AS "CommentNiin", d1.author_uid AS "AuthorUid", d1.comment_text AS "Text", d1.parent_comment_id AS "ParentCommentId", (
      SELECT u.username
      FROM database_item_comments AS d
      INNER JOIN users AS u ON d.author_uid = u.uid
      LIMIT 1) AS "Username", (
      SELECT u0.uid
      FROM database_item_comments AS d0
      INNER JOIN users AS u0 ON d0.author_uid = u0.uid
      LIMIT 1) AS "Uid"
  FROM database_item_comments AS d1

I know it's due to the way I'm retrieving the user values being incredibly inefficient, what would be the correct way to complete this query while only making a single call to the users table?我知道这是由于我检索用户值的方式非常低效,在只对用户表进行一次调用的同时完成此查询的正确方法是什么?

Preferably just querying the comment table directly, and returning the full Comment entity sans DTO, without having to map the variables, while creating the UserDto for the Comment and mapping the values最好直接查询评论表,并返回完整的评论实体无 DTO,而不必 map 变量,同时为评论创建 UserDto 并映射值

Your Comment entity should have a reference to a User entity, which would see your query corrected to:您的 Comment 实体应该具有对 User 实体的引用,这将使您的查询更正为:

        var comments = await dbSet.
        Where(c => c.commentPn == sentPn)
       .Select(c => new CommentDto
        {
            CommentId = c.CommentId,
            CommentPn = c.CommentPn,
            AuthorUid = c.AuthorUid,
            Text = c.Text,
            ParentCommentId = c.ParentCommentId,
            User = new UserDto 
            {
                UId = c.User.UId,
                Username = c.User.Username
            });
        }).ToListAsync();

Your example would potentially fail if you have multiple comments in the DB as to populate the user DTO you were effectively telling it to load all comments ( DbSet.Select ) to get at the User and expect only 1 result via Single() .如果您在数据库中有多个评论来填充用户 DTO,您的示例可能会失败,您实际上是告诉它加载所有评论( DbSet.Select )以获取用户并期望通过Single()只有 1 个结果。 Then there is the fact that you are executing that twice, once to select the ID, and then to select the name.然后是你执行了两次,一次是 select ID,然后是 select 名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM