实体框架在不询问的情况下填充子实体

时间:2016-02-18 21:39:31

标签: c# entity-framework asp.net-web-api entity-framework-6

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

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序列化对象时我们没有得到任何引用循环。

1 个答案:

答案 0 :(得分:0)

  

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

没有。您无法禁用此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.
        });
}