1

We're pulling data for Users using Entity Framework code similar to what is below:

using (DataContext db = new DataContext())
{
    var users = db.Users.Include("Roles.Role");
}

This effectively gets the Roles and Logins that we're looking for. However, because Role also has Users on it for the users in that role, it's also being populated. That means we get a result similar to what's below:

[{
        "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
    }]

We're not explicitly requesting that the Users on the Role be loaded, but it seems like it's loading them because it already knows who they are because it loaded the users as part of the main request.

We have lazy loading disabled and do not have any properties marked a virtual.

Is there anyway to keep it from doing this? I did some searching and most people are asking how to get child objects to populate, not how to keep them from populating when they're not requested.

UPDATE: To further explain, this is happening before any sort of serialization by ASP.NET, immediately after it comes from the data context, and we are not getting any reference loops when the objects are serialized from WebAPI.

amrinea
  • 383
  • 1
  • 11
  • Especially [this answer](http://stackoverflow.com/a/30276521/861716). – Gert Arnold Feb 18 '16 at 22:56
  • I don't think this is a duplicate. This is happening immediately after the entities are loaded from the data context and before any serialization occurs. We also are not getting any sort of reference loops when it serializes since it does appear to stop referencing itself over and over again as you can see in the roles being empty on the deepest level of the users. – amrinea Feb 19 '16 at 03:36
  • If you serialize `db.Users.Include("Roles.Role")`, with the approach in the referred answer it should not serialize `Role.Users` even though the entities are loaded. – Gert Arnold Feb 19 '16 at 07:01

1 Answers1

0

Is there anyway to keep it from doing this? I did some searching and most people are asking how to get child objects to populate, not how to keep them from populating when they're not requested.

No. You can't disable this DbContext behavior.

The best way and most recommended is to use a view model which is a class you create that will contain and expose, via properties, only data you need to return. This is the DTO pattern.

You must have something like this:

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.
        });
}
CodeNotFound
  • 20,646
  • 10
  • 62
  • 67
  • I thought we might have to go this route, but couldn't find anything to verify this behavior exists or whether or not it could be enabled or disabled before we started rearchitecting the code. Thanks! – amrinea Feb 19 '16 at 03:41