温馨提示:本文翻译自stackoverflow.com,查看原文请点击:asp.net - EF core include multiple relations getting unwanted data
asp.net entity-framework

asp.net - EF核心包括获取不必要数据的多个关系

发布于 2020-03-31 23:44:55

我是一个模特关系如下

邮政模型

public class Post : BaseEntity
    {
        public int Id { get; set; }
        public string Content { get; set; }
        public string Image { get; set; }

        public virtual User User { get; set; }
        [Column( "user_id" )] public string UserId { get; set; }

        public virtual  List< Comment > Comments { get; set; }
    }

用户模型

public class User : IdentityUser
    {
        public string FirstName { get; set; }

        public string MiddleName { get; set; }

        public string LastName { get; set; }

        [Column( "created_at", Order = 254 )] public DateTime CreatedAt { get; set; }
        [Column( "updated_at", Order = 255 )] public DateTime UpdatedAt { get; set; }

        public virtual ICollection< Post > Posts { get; set; }
        public virtual ICollection< Comment > Comments { get; set; }
    }

评论模型

public class Comment : BaseEntity
    {
        public int Id { get; set; }
        public string Content { get; set; }
        public virtual User User { get; set; }
        [Column( "user_id" )] public string UserId { get; set; }
        public virtual Post Post { get; set; }
        [Column( "post_id" )] public int PostId { get; set; }
    }

当我这样做时

public IEnumerable< Post > GetAllPosts()
        {
            return dbContext.Posts
                .Include( post => post.User )
                .ThenInclude( post => post.Comments )
                .ToList();
        }

我得到了多个深度的数据。我只需要一个孩子

这是我的帖子输出。数据正在重复。

[
    {
        "id": 5,
        "content": "This post is about fires going on in NSW",
        "image": null,
        "user": { 
            "firstName": "Bikram",
            "middleName": null,
            "lastName": "Bhandari",
            "createdAt": "0001-01-01T00:00:00",
            "updatedAt": "0001-01-01T00:00:00",
            "posts": [], --I don't want this
            "comments": [  -- Unwanted
                {
                    "id": 7,
                    "content": "So sad to see this",
                    "userId": "052b4889-431f-48d2-b673-5835166c03ee",
                    "postId": 5,
                    "createdAt": "0001-01-01T00:00:00",
                    "updatedAt": "0001-01-01T00:00:00"
                },
                {
                    "id": 8,
                    "content": "Let's hope for a rain",
                    "userId": "052b4889-431f-48d2-b673-5835166c03ee",
                    "postId": 5,
                    "createdAt": "0001-01-01T00:00:00",
                    "updatedAt": "0001-01-01T00:00:00"
                }
            ],
            "id": "052b4889-431f-48d2-b673-5835166c03ee",
            "userName": "bikrambhandari48@gmail.com",
            "normalizedUserName": "BIKRAMBHANDARI48@GMAIL.COM",
            "email": "bikrambhandari48@gmail.com",
            "normalizedEmail": "BIKRAMBHANDARI48@GMAIL.COM",
            "emailConfirmed": false,
            "passwordHash": "AQAAAAEAACcQAAAAEHBFj2Woq4/JhqyPWtaXt2xjL4+ML9XQR24pYJsvUAaAKWr/Pg4NgQ2S/O1h8fkerg==",
            "securityStamp": "XVNJKDOYMMT6SP2LLBUNHRKWGT3NZB4X",
            "concurrencyStamp": "2658eced-edd7-4458-b9e2-a010b46e3f37",
            "phoneNumber": null,
            "phoneNumberConfirmed": false,
            "twoFactorEnabled": false,
            "lockoutEnd": null,
            "lockoutEnabled": true,
            "accessFailedCount": 0
        },
        "userId": "052b4889-431f-48d2-b673-5835166c03ee",
        "comments": [
            {
                "id": 7,
                "content": "So sad to see this",
                "user": { --Not wanted
                    "firstName": "Bikram",
                    "middleName": null,
                    "lastName": "Bhandari",
                    "createdAt": "0001-01-01T00:00:00",
                    "updatedAt": "0001-01-01T00:00:00",
                    "posts": [],
                    "comments": [ --Not wanted
                        {
                            "id": 8,
                            "content": "Let's hope for a rain",
                            "userId": "052b4889-431f-48d2-b673-5835166c03ee",
                            "postId": 5,
                            "createdAt": "0001-01-01T00:00:00",
                            "updatedAt": "0001-01-01T00:00:00"
                        }
                    ],
                    "id": "052b4889-431f-48d2-b673-5835166c03ee",
                    "userName": "bikrambhandari48@gmail.com",
                    "normalizedUserName": "BIKRAMBHANDARI48@GMAIL.COM",
                    "email": "bikrambhandari48@gmail.com",
                    "normalizedEmail": "BIKRAMBHANDARI48@GMAIL.COM",
                    "emailConfirmed": false,
                    "passwordHash": "AQAAAAEAACcQAAAAEHBFj2Woq4/JhqyPWtaXt2xjL4+ML9XQR24pYJsvUAaAKWr/Pg4NgQ2S/O1h8fkerg==",
                    "securityStamp": "XVNJKDOYMMT6SP2LLBUNHRKWGT3NZB4X",
                    "concurrencyStamp": "2658eced-edd7-4458-b9e2-a010b46e3f37",
                    "phoneNumber": null,
                    "phoneNumberConfirmed": false,
                    "twoFactorEnabled": false,
                    "lockoutEnd": null,
                    "lockoutEnabled": true,
                    "accessFailedCount": 0
                },
                "userId": "052b4889-431f-48d2-b673-5835166c03ee",
                "postId": 5,
                "createdAt": "0001-01-01T00:00:00",
                "updatedAt": "0001-01-01T00:00:00"
            },
            { --Not wanted
                "id": 8,
                "content": "Let's hope for a rain",
                "user": {
                    "firstName": "Bikram",
                    "middleName": null,
                    "lastName": "Bhandari",
                    "createdAt": "0001-01-01T00:00:00",
                    "updatedAt": "0001-01-01T00:00:00",
                    "posts": [],
                    "comments": [
                        {
                            "id": 7,
                            "content": "So sad to see this",
                            "userId": "052b4889-431f-48d2-b673-5835166c03ee",
                            "postId": 5,
                            "createdAt": "0001-01-01T00:00:00",
                            "updatedAt": "0001-01-01T00:00:00"
                        }
                    ],
                    "id": "052b4889-431f-48d2-b673-5835166c03ee",
                    "userName": "bikrambhandari48@gmail.com",
                    "normalizedUserName": "BIKRAMBHANDARI48@GMAIL.COM",
                    "email": "bikrambhandari48@gmail.com",
                    "normalizedEmail": "BIKRAMBHANDARI48@GMAIL.COM",
                    "emailConfirmed": false,
                    "passwordHash": "AQAAAAEAACcQAAAAEHBFj2Woq4/JhqyPWtaXt2xjL4+ML9XQR24pYJsvUAaAKWr/Pg4NgQ2S/O1h8fkerg==",
                    "securityStamp": "XVNJKDOYMMT6SP2LLBUNHRKWGT3NZB4X",
                    "concurrencyStamp": "2658eced-edd7-4458-b9e2-a010b46e3f37",
                    "phoneNumber": null,
                    "phoneNumberConfirmed": false,
                    "twoFactorEnabled": false,
                    "lockoutEnd": null,
                    "lockoutEnabled": true,
                    "accessFailedCount": 0
                },
                "userId": "052b4889-431f-48d2-b673-5835166c03ee",
                "postId": 5,
                "createdAt": "0001-01-01T00:00:00",
                "updatedAt": "0001-01-01T00:00:00"
            }
        ],
        "createdAt": "0001-01-01T00:00:00",
        "updatedAt": "0001-01-01T00:00:00"
    }
]

如果您在上面看到,则可以看到数据在重复。检索所有帖子以及与该帖子相关联的用户以及帖子的所有评论,我在做错什么?谁能建议我应该如何定义模型关系以更好地检索数据?我也想从用户的角度检索所有帖子和评论。在评论模型中,我想知道评论属于哪个帖子,谁也是评论的所有者。先感谢您。

查看更多

提问者
Bikram
被浏览
76
David Browne - Microsoft 2020-01-31 22:00

变更跟踪器将在加载实体时修复关系。因此,如果您加载帖子的评论,并且已经为其中一些评论加载了用户,则将设置用户和评论之间的导航属性。

如果启用了更改跟踪,则在加载实体时,EF Core会自动将新加载的实体的导航属性设置为引用任何已加载的实体,并将已加载的实体的导航属性设置为引用新实体。加载的实体。

加载相关数据-EF核心:显式加载

在DbContext上禁用更改跟踪以防止此行为,

public IList< Post > GetAllPosts()
{
    return dbContext.Posts.AsNoTracking()
        .Include( post => post.User )
        .ThenInclude( post => post.Comments )
        .ToList();
}

然后返回IList<T>,而不是IEnumerable<T>,否则您的呼叫者将不会知道这是否是流式结果,并且可能会以防御方式将结果加载到列表中。

或者,在JSON序列化程序中指定文档的形状。