实体框架在不询问的情况下填充子实体[重复]

Posted

技术标签:

【中文标题】实体框架在不询问的情况下填充子实体[重复]【英文标题】:Entity Framework populating child entities without asking [duplicate] 【发布时间】:2016-05-31 07:06:21 【问题描述】:

我们正在使用类似于下面的实体框架代码为用户提取数据:

using (DataContext db = new DataContext())

    var users = db.Users.Include("Roles.Role");

这有效地获取了我们正在寻找的角色和登录名。但是,由于 Role 上还为该角色中的用户提供了用户,因此它也会被填充。这意味着我们得到的结果类似于以下内容:

[
        "roles" : [
                "userId" : 1,
                "roleId" : 1,
                "role" : 
                    "users" : [
                            "userId" : 4,
                            "user" : 
                                "roles" : [],
                                "firstName" : "Jill",
                                "lastName" : "Doe",
                                "id" : 4
                            ,
                            "roleId" : 1
                        , 
                            "userId" : 1,
                            "user" : 
                                "roles" : [],
                                "firstName" : "John",
                                "lastName" : "Doe",
                                "id" : 1
                            ,
                            "roleId" : 1
                        
                    ],
                    "id" : 1,
                    "name" : "Administrator"
                
            
        ],
        "firstName" : "John"
        "lastName" : "Doe"
        "id" : 1
    ]

我们没有明确要求加载角色上的用户,但它似乎正在加载他们,因为它已经知道他们是谁,因为它加载了用户作为主请求的一部分。

我们禁用了延迟加载,并且没有任何属性标记为虚拟

有没有办法阻止它这样做?我做了一些搜索,大多数人都在问如何让子对象填充,而不是如何在没有请求时阻止它们填充。

更新:为了进一步解释,这发生在 ASP.NET 进行任何类型的序列化之前,它来自数据上下文之后,当对象从 WebAPI 序列化时,我们没有得到任何引用循环。

【问题讨论】:

尤其是this answer。 我不认为这是重复的。这发生在从数据上下文加载实体之后和任何序列化发生之前。当它序列化时,我们也没有得到任何类型的引用循环,因为它似乎会一次又一次地停止引用自己,正如您在用户最深层的角色中看到的那样是空的。 如果您序列化db.Users.Include("Roles.Role"),使用参考答案中的方法,即使加载了实体,它也不应该序列化Role.Users 【参考方案1】:

有没有办法阻止它这样做?我做了一些搜索和 大多数人都在问如何让子对象填充,而不是如何 以防止它们在不被请求时填充。

没有。您不能禁用此 DbContext 行为。

最好和最推荐的方法是使用视图模型,它是您创建的一个类,它将通过属性仅包含和公开您需要返回的数据。这是DTO pattern。

你必须有这样的东西:

using (DataContext db = new DataContext())

    var users = db.Users
        .Include("Roles.Role")
        .Select(user => new MyDtoClass() 
             // TODO you set here you DTO properties eg. FirstName, LastName, Role Name etc... and not your complete entity object.
        );

【讨论】:

我认为我们可能不得不走这条路,但在我们开始重新架构代码之前,找不到任何东西来验证这种行为是否存在,或者是否可以启用或禁用它。谢谢!

以上是关于实体框架在不询问的情况下填充子实体[重复]的主要内容,如果未能解决你的问题,请参考以下文章

实体框架使用外键填充子对象

实体框架:查询子实体 [重复]

具有实体框架 6 的 ObjectContext 在现有相关实体上插入重复项

如何在不更新具有多对多关系的子实体的情况下保留父实体?

在不更新行版本的情况下检查实体的并发性

在不使用其他项目的情况下添加实体框架核心迁移